在弹性搜索中存储嵌套对象

时间:2018-09-27 06:34:05

标签: elasticsearch

我有一个3级嵌套对象,如下所示,我想在弹性搜索中为这些对象建立索引。这里的要求是用户将编写一个搜索查询关键字,例如“ keyword1 keyword2 ...”,我想返回包含所有这些关键字的对象(在任何级别,即AND操作)。

   [  
   {  
      "country":[  
         {  
            "name":"India",
            "ext_code":"91",
            "states":[  
               {  
                  "name":"Karnataka",
                  "ext_code":"04",
                  "cities":[  
                     {  
                        "name":"Bangalore",
                        "ext_code":"080"
                     }
                  ]
               }
            ]
         }
      ]
   }
]

当前,我使用以下映射以嵌套格式存储它们:

{
    "mappings":{
        "doc":{
            "properties":{
                "name": {"type":"text"},
                "ext_code": {"type":"text"}
                "state" {
                    "type": "nested",
                    "properties": {
                        "name": {"type":"text"},
                        "ext_code": {"type":"text"}
                        "city" {
                            "type": "nested",
                            "properties": {
                                "name": {"type":"text"}
                                "ext_code": {"type":"text"}
                            }
                        }
                    }
                }
            }
        }
    }
}

在搜索时,我通过弹性搜索嵌套查询来搜索所有级别,如下所示:

{
    "query": {
        "bool": {
            "should": [
                {
                    "multi_match": {
                        "query": "keyword1 keyword2 ...",
                        "fields": ['name'] 
                    }
                },
                {
                    "nested": {
                        "path": 'state',
                        "query": {
                            "multi_match": {
                                "query": "keyword1 keyword2 ...",
                                "fields": ['state.name']
                            }
                        }
                    }
                },
                {
                    "nested": {
                        "path": 'state.city',
                        "query": {
                            "multi_match": {
                                "query": "keyword1 keyword2 ...",
                                "fields": ['state.city.name']
                            }
                        }
                    }
                }
            ]
        }
    }
}

在发送多个令牌进行搜索时,它会执行“或”运算,返回包含任何搜索令牌的文档。

是否可以将Elastic Search配置为对搜索查询中的多个令牌执行AND操作?

3 个答案:

答案 0 :(得分:3)

一种解决方案是索引自定义all fieldname字段的所有值。首先像这样定义索引和映射:

PUT index
{
  "mappings": {
    "doc": {
      "properties": {
        "all": {                 <-- all field that will contain all values
          "type": "text"
        },
        "name": {
          "type": "text",
          "copy_to": "all"       <-- copy value to all field
        },
        "ext_code": {
          "type": "text"
        },
        "state": {
          "type": "nested",
          "properties": {
            "name": {
              "type": "text",
              "copy_to": "all"       <-- copy value to all field
            },
            "ext_code": {
              "type": "text"
            },
            "city": {
              "type": "nested",
              "properties": {
                "name": {
                  "type": "text",
                  "copy_to": "all"       <-- copy value to all field
                },
                "ext_code": {
                  "type": "text"
                }
              }
            }
          }
        }
      }
    }
  }
}

然后为您的文档编制索引:

POST index/doc
{
  "name": "India",
  "ext_code": "91",
  "state": [
    {
      "name": "Karnataka",
      "ext_code": "04",
      "city": [
        {
          "name": "Bangalore",
          "ext_code": "080"
        }
      ]
    }
  ]
}

最后,使用简单的匹配查询,您可以在文档中的任何位置搜索任何值:

POST index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "all": {
              "query": "bangalore india",
              "operator": "and"
            }
          }
        }
      ]
    }
  }
}

答案 1 :(得分:0)

请尝试关注

{
    "query": {
        "bool": {
            "should": [
                {
                    "simple_query_string": {
                        "query": "keyword1 keyword2 ...",
                        "fields": ['name'] ,
                        "default_operator": "and"
                    }
                },
                {
                    "nested": {
                        "path": 'state',
                        "query": {
                            "simple_query_string": {
                                "query": "keyword1 keyword2 ...",
                                "fields": ['state.name'],
                                "default_operator": "and"
                            }
                        }
                    }
                },
                {
                    "nested": {
                        "path": 'state.city',
                        "query": {
                            "simple_query_string": {
                                "query": "keyword1 keyword2 ...",
                                "fields": ['state.city.name'],
                                "default_operator": "and"
                            }
                        }
                    }
                }
            ]
        }
    }
}

我认为multi_match不能满足此要求。简单查询字符串或查询字符串查询更适合于此目的。

答案 2 :(得分:-2)

根据我的理解,我认为nitzien提到的内容在这里不起作用。如果关键字跨越不同级别,则在所有级别上执行AND操作都可能返回0结果。