Elastic Search запрашивает вложенный и родительский атрибут - PullRequest
0 голосов
/ 11 октября 2019

У меня есть эластичный документ, как показано ниже.

{
  "process_id" : "123",
  "user_info" : [{
     "first_name":"A",
     "last_name: "B"
   }]
}

{
  "process_id" : "123",
  "user_info" : [{
     "first_name":"C",
     "last_name: "B"
 }, 
  {"first_name" : "A", 
  "last_name":"D"
  } ]
}

Сценарий 1:

Я не установил вложенный тип в поле "user_info". Я ищу "process_id" как 123 и first_name как A и last_name как B, я получаю оба документа в результате.

Сценарий 2:

Поиск возвращаетошибка. Похоже, я не смогу искать вложенный элемент и тот, который находится в родительском элементе.

Запрос выглядит следующим образом:

{


 "query": {
    "query_string": {
      "query": "process_id:123",
      "nested": {
        "path": "user_info",
        "query": {
          "query_string": {
            "query": "(user_info.first_name:A AND user_info.last_name:B"
          }
        }
      }
    }   } }

Ответ об ошибке, как показано ниже.

{
"error": {
"root_cause": [
{
"type": "parsing_exception",
"reason": "[query_string] unknown token [START_OBJECT] after [nested]",
"line": 1
}
],
"type": "parsing_exception",
"reason": "[query_string] unknown token [START_OBJECT] after [nested]",
"line": 1,

},
"status": 400
}

Идеальный ответ должен быть, когда я ищу для process_id как 123, first_name как A и last_name как B, должен быть возвращен только первый документ.

Примечание: атрибутимена хранятся в общих целях, чтобы их можно было проиллюстрировать.

1 Ответ

2 голосов
/ 12 октября 2019

Я вижу следующие 2 проблемы в вашем Сценарии 2

  • , чтобы объединить запросы, вам нужно использовать bool -запрос
  • , чтобы сделать nested -Запросы работают, вам нужно определить родительское поле как nested -поле

1. Объявите поле user_info с типом nested в ваших сопоставлениях:

PUT processes
{
  "mappings": {
    "properties": {
      "process_id": {
        "type": "keyword"
      },
      "user_info": {
        "type": "nested",
        "properties": {
          "first_name": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "last_name": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }
  }
}

Примечание: сопоставление для user_info с дополнительной строкой "type": "nested"

2. Индексируйте 2 предоставленных вами образца документов

POST processes/_bulk
{"index":{"_id":1}}
{"process_id": "123", "user_info": [{"first_name": "A", "last_name": "B"}]}
{"index":{"_id":2}}
{"process_id": "123", "user_info": [{"first_name": "C", "last_name": "B"},{"first_name": "A", "last_name": "D"}]}

3. Запрос на комбинацию first_name и last_name с использованием nested -запроса

GET processes/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "process_id": {
              "value": "123"
            }
          }
        },
        {
          "nested": {
            "path": "user_info",
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "user_info.first_name": "A"
                    }
                  },
                  {
                    "match": {
                      "user_info.last_name": "B"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

Примечание: search_request ищет все документы, которые соответствуют process_id (123) и комбинации user_info.first_name и user_info.last_name для одного конкретного пользователя (а не для разных пользователей). В приведенной выше настройке запрос соответствует только документу 1. Если вы хотите, чтобы Elasticsearch также сообщал вам, какая user_info вызвала совпадение (в случае, если у процесса есть несколько объектов user_info), вы можете добавить следующее условие в ваш вложенный запрос: "inner_hits": {}.

Возможно, вы задались вопросом, почему я сопоставил поле process_id с полем keyword. Это лучшая практика, поскольку keyword является наиболее эффективным типом для хранения идентификаторов.

Ссылка в документации Elasticsearch: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html

Обновление 13 октября 2019 г .: Добавлена ​​версия с использованием queryString -запрос

GET processes/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "process_id:123"
            }
        },
        {
          "nested": {
            "path": "user_info",
            "query": {
              "query_string": {
                "query": "user_info.first_name:A AND user_info.last_name:B"
              }
            }
          }
        }
      ]
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...