zoukankan      html  css  js  c++  java
  • elasticsearch 嵌套对象之嵌套类型

    nested类型是一种特殊的对象object数据类型(specialised version of the object datatype ),允许对象数组彼此独立地进行索引和查询。

    1. 对象数组如何扁平化

    内部对象object字段的数组不能像我们所期望的那样工作。 Lucene没有内部对象的概念,所以Elasticsearch将对象层次结构扁平化为一个字段名称和值的简单列表。 例如,以下文件:

    curl -XPUT 'localhost:9200/my_index/my_type/1?pretty' -H 'Content-Type: application/json' -d'
    {
      "group" : "fans",
      "user" : [ 
        {
          "first" : "John",
          "last" :  "Smith"
        },
        {
          "first" : "Alice",
          "last" :  "White"
        }
      ]
    }
    '
    

    说明

    user字段被动态的添加为object类型的字段。

    在内部其转换成一个看起来像下面这样的文档:

    {
      "group" :        "fans",
      "user.first" : [ "alice", "john" ],
      "user.last" :  [ "smith", "white" ]
    }
    

    user.firstuser.last字段被扁平化为多值字段,并且alicewhite之间的关联已经丢失。 本文档将错误地匹配user.firstaliceuser.lastsmith的查询:

    curl -XGET 'localhost:9200/my_index/_search?pretty' -H 'Content-Type: application/json' -d'
    {
      "query": {
        "bool": {
          "must": [
            { "match": { "user.first": "Alice" }},
            { "match": { "user.last":  "Smith" }}
          ]
        }
      }
    }
    '
    

    2. 对对象数组使用嵌套字段

    如果需要索引对象数组并维护数组中每个对象的独立性,则应使用nested数据类型而不是object数据类型。 在内部,嵌套对象将数组中的每个对象作为单独的隐藏文档进行索引,这意味着每个嵌套对象都可以使用嵌套查询nested query独立于其他对象进行查询:

    curl -XPUT 'localhost:9200/my_index?pretty' -H 'Content-Type: application/json' -d'
    {
      "mappings": {
        "my_type": {
          "properties": {
            "user": {
              "type": "nested" 
            }
          }
        }
      }
    }
    '
     
    curl -XPUT 'localhost:9200/my_index/my_type/1?pretty' -H 'Content-Type: application/json' -d'
    {
      "group" : "fans",
      "user" : [
        {
          "first" : "John",
          "last" :  "Smith"
        },
        {
          "first" : "Alice",
          "last" :  "White"
        }
      ]
    }
    '
    

    说明

    user字段映射为nested类型,而不是默认的object类型


    curl -XGET 'localhost:9200/my_index/_search?pretty' -H 'Content-Type: application/json' -d'
    {
      "query": {
        "nested": {
          "path": "user",
          "query": {
            "bool": {
              "must": [
                { "match": { "user.first": "Alice" }},
                { "match": { "user.last":  "Smith" }} 
              ]
            }
          }
        }
      }
    }
    '
    

    说明

    此查询得不到匹配,是因为AliceSmith不在同一个嵌套对象中。


    curl -XGET 'localhost:9200/my_index/_search?pretty' -H 'Content-Type: application/json' -d'
    {
      "query": {
        "nested": {
          "path": "user",
          "query": {
            "bool": {
              "must": [
                { "match": { "user.first": "Alice" }},
                { "match": { "user.last":  "White" }} 
              ]
            }
          },
          "inner_hits": { 
            "highlight": {
              "fields": {
                "user.first": {}
              }
            }
          }
        }
      }
    }
    '
    

    说明

    此查询得到匹配,是因为AliceWhite位于同一个嵌套对象中。

    inner_hits允许我们突出显示匹配的嵌套文档。

    输出

    {
        "took": 151,
        "timed_out": false,
        "_shards": {
            "total": 5,
            "successful": 5,
            "skipped": 0,
            "failed": 0
        },
        "hits": {
            "total": 1,
            "max_score": 1.3862944,
            "hits": [
                {
                    "_index": "indextest010",
                    "_type": "my_type",
                    "_id": "1",
                    "_score": 1.3862944,
                    "_source": {
                        "group": "fans",
                        "user": [
                            {
                                "first": "John",
                                "last": "Smith"
                            },
                            {
                                "first": "Alice",
                                "last": "White"
                            }
                        ]
                    },
                    "inner_hits": {
                        "user": {
                            "hits": {
                                "total": 1,
                                "max_score": 1.3862944,
                                "hits": [
                                    {
                                        "_index": "indextest010",
                                        "_type": "my_type",
                                        "_id": "1",
                                        "_nested": {
                                            "field": "user",
                                            "offset": 1
                                        },
                                        "_score": 1.3862944,
                                        "_source": {
                                            "first": "Alice",
                                            "last": "White"
                                        },
                                        "highlight": {
                                            "user.first": [
                                                "<em>Alice</em>"
                                            ]
                                        }
                                    }
                                ]
                            }
                        }
                    }
                }
            ]
        }
    }

    嵌套文档可以:

    3. 嵌套字段参数

    嵌套字段接受以下参数:

    参数 描述
    dynamic 是否将新属性动态添加到现有的嵌套对象。共有true(默认),falsestrict三种参数。
    include_in_all Sets the default include_in_all value for all the properties within the nested object. Nested documents do not have their own _all field. Instead, values are added to the _all field of the main “root” document.
    properties 嵌套对象中的字段,可以是任何数据类型,包括嵌套。新的属性可能会添加到现有的嵌套对象。

    备注

    类型映射(type mapping)、对象字段和嵌套字段包含的子字段,称之为属性properties。这些属性可以为任意数据类型,包括object和 nested。属性可以通过以下方式加入:

    • 当在创建索引时显式定义他们。
    • 当使用PUT mapping API添加或更新映射类型时显式地定义他们。
    • 当索引包含新字段的文档时动态的加入。

    重要

    由于嵌套文档作为单独的文档进行索引,因此只能在nested查询,nested/reverse_nested聚合或者 nested inner hits 的范围内进行访问。

    For instance, if a string field within a nested document has index_options set to offsets to allow use of the postings highlighter, these offsets will not be available during the main highlighting phase. Instead, highlighting needs to be performed via nested inner hits.

    4. 限制嵌套字段的个数

    索引一个拥有100个嵌套字段的文档,相当于索引了101个文档,因为每一个嵌套文档都被索引为一个独立的文档.为了防止不明确的映射,每个索引可以定义的嵌套字段的数量已被限制为50个。 具体请参阅 Settings to prevent mappings explosion

    原文:https://www.elastic.co/guide/en/elasticsearch/reference/current/nested.html#nested-params

    补充更新2018年7月30日


    多嵌套查询方式:

    {
        "query": {
            "bool": {
                "must": [
                    {
                        "nested": {
                            "path": [
                                "ajxx"
                            ],
                            "query": {
                                "bool": {
                                    "must": [
                                        {
                                            "match": {
                                                "ajxx.ajmc": "案件名称"
                                            }
                                        },
                                        {
                                            "range": {
                                                "ajxx.sasj": {
                                                    "gte": "2015-01-01 12:10:10",
                                                    "lte": "2015-01-01 12:10:40"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    {
                        "nested": {
                            "path": [
                                "rqxx"
                            ],
                            "query": {
                                "bool": {
                                    "must": [
                                        {
                                            "range": {
                                                "rqxx.rqsj": {
                                                    "gte": "2015-01-01 12:10:10",
                                                    "lte": "2015-01-01 12:10:40"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                ]
            }
        }
    }

    2018年7月31日 16:59:14更新

    全文及条件检索

    {
        "query": {
            "bool": {
                "must": [
                    {
                        "nested": {
                            "path": [
                                "ajxx"
                            ],
                            "query": {
                                "bool": {
                                    "must": [
                                        {
                                            "match": {
                                                "ajxx.ajzt": "破案"
                                            }
                                        },
                                        {
                                            "range": {
                                                "ajxx.sasj": {
                                                    "gte": "2017-01-01 12:10:10",
                                                    "lte": "2017-01-02 12:10:40"
                                                }
                                            }
                                        }
                                    ],
                                    "should": [
                                        {
                                            "bool": {
                                                "must": [
                                                    {
                                                        "query_string": {
                                                            "query": "20170316盗窃案"
                                                        }
                                                    }
                                                ]
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                ]
            }
        }
    }

    多嵌套且全文检索 

    {
        "query": {
            "bool": {
                "must": [
                    {
                        "nested": {
                            "path": [
                                "ajxx"
                            ],
                            "query": {
                                "bool": {
                                    "must": [
                                        {
                                            "match": {
                                                "ajxx.ajmc": "案件名称"
                                            }
                                        },
                                        {
                                            "range": {
                                                "ajxx.sasj": {
                                                    "gte": "2015-01-01 12:10:10",
                                                    "lte": "2015-01-01 12:10:40"
                                                }
                                            }
                                        },
                                        {
                                            "query_string": {
                                                "query": "物品状态"
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    {
                        "nested": {
                            "path": [
                                "rqxx"
                            ],
                            "query": {
                                "bool": {
                                    "must": [
                                        {
                                            "range": {
                                                "rqxx.rqsj": {
                                                    "gte": "2015-01-01 12:10:10",
                                                    "lte": "2015-01-01 12:10:40"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                ]
            }
        }
    }

    最后精简

    {
        "query": {
            "bool": {
                "must": [
                    {
                        "nested": {
                            "path": [
                                "ajxx"
                            ],
                            "query": {
                                "bool": {
                                    "must": [
                                        {
                                            "match": {
                                                "ajxx.ajzt": "破案"
                                            }
                                        },
                                        {
                                            "range": {
                                                "ajxx.sasj": {
                                                    "gte": "2017-01-01 12:10:10",
                                                    "lte": "2017-01-02 12:10:40"
                                                }
                                            }
                                        }
                                    ],
                                    "should": [
                                        {
                                            "query_string": {
                                                "query": "20170316盗窃案"
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                ]
            }
        }
    }

    查询字段名称的模糊匹配编辑
    字段名称可以用模糊匹配的方式给出:任何与模糊模式正则匹配的字段都会被包括在搜索条件中

    {
        "multi_match": {
            "query":  "结果",
            "fields": ["*","*_title"]
        }
    }

    当这些子字段出现数值类型的时候,就会报异常了,解决方法是加入lenient字段

    {
        "type": "parse_exception",
        "reason": "failed to parse date field [XXX] with format [yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis]"
    }
    {
        "multi_match": {
            "query": "结果",
            "lenient": "true",
            "fields": ["*"]
        }
    }

    利用multi_match嵌套全文检索

    "include_in_parent":true,
    "include_in_root":true,
    {
        "query": {
            "bool": {
                "must": [
                    {
                        "match": {
                            "ajztmc": "立案"
                        }
                    },
                    {
                        "match": {
                            "ajlxmc": "刑事"
                        }
                    },
                    {
                        "range": {
                            "lasj": {
                                "gte": "2015-01-01 12:10:10",
                                "lte": "2016-01-01 12:10:40"
                            }
                        }
                    },
                    {
                        "nested": {
                            "path": [
                                "rqxx"
                            ],
                            "query": {
                                "bool": {
                                    "must": [
                                        {
                                            "match": {
                                                "rqxx.baqmc": "办案区名称"
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    {
                        "nested": {
                            "path": [
                                "saryxx"
                            ],
                            "query": {
                                "bool": {
                                    "must": [
                                        {
                                            "match": {
                                                "saryxx.rylxmc": "嫌疑人"
                                            }
                                        },
                                        {
                                            "match": {
                                                "saryxx.ryxb": "女"
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    {
                        "nested": {
                            "path": [
                                "wp"
                            ],
                            "query": {
                                "bool": {
                                    "must": [
                                        {
                                            "match": {
                                                "wp.wpzlmc": "赃物"
                                            }
                                        },
                                        {
                                            "match": {
                                                "wp.wpztmc": "物品入库"
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    {
                        "multi_match": {
                            "query": "男",
                            "lenient": "true",
                            "fields": [
                                "*"
                            ]
                        }
                    }
                ]
            }
        },
        "from": 0,
        "size": 100,
        "sort": {
            "zxxgsj": {
                "order": "desc"
            }
        }
    }

    参考:

    https://www.elastic.co/guide/cn/elasticsearch/guide/current/multi-match-query.html

    http://www.bubuko.com/infodetail-2153060.html

    https://www.cnblogs.com/huangfox/p/3544883.html

  • 相关阅读:
    LeetCode之移除元素
    有被开心到hh(日常)
    交换排序
    插入排序
    顺序查找&折半查找
    C++之引用
    MySQL学习笔记
    C/C++程序编译过程
    计算机面试知识整合(更新中...)
    MFC之编辑框
  • 原文地址:https://www.cnblogs.com/gmhappy/p/9472382.html
Copyright © 2011-2022 走看看