Хранение вложенных объектов в упругом поиске - PullRequest
0 голосов
/ 27 сентября 2018

У меня есть вложенный объект 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 для выполнения операции И длянесколько токенов в поисковом запросе?

Ответы [ 2 ]

0 голосов
/ 01 октября 2018

Одним из решений будет индексация всех значений полей name внутри пользовательского поля all .Сначала определите ваш индекс и сопоставления следующим образом:

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"
            }
          }
        }
      ]
    }
  }
}
0 голосов
/ 27 сентября 2018

Пожалуйста, попробуйте выполнить следующие действия:

{
    "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 подходит для этого требования.Простая строка запроса или запрос строки запроса лучше подходит для этой цели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...