ElasticSearch 2.4 - запрос строки ИЛИ между основным типом и вложенным - PullRequest
4 голосов
/ 27 января 2020

Я использую ElasticSearch 2.4

Мне нужно создать поисковый запрос между основным объектом и вложенным объектом, если я использую условие AND, оно работает правильно, но проблема в том, если я пытаюсь использовать условное ИЛИ между основным объектом и вложенным объектом: просмотрите приведенный ниже код и скажите, есть ли способ заставить его работать, используя условное ИЛИ.

Создать сопоставление:

PUT /example_contact_purchases
{
  "mappings": {
    "contact": {
      "dynamic": false,
      "properties": {
        "name": {
          "type": "string"
        },
        "country": {
          "type": "string"
        },
        "purchases": {
          "type": "nested",
          "properties": {
            "uuid":{
              "type":"string"
            }
          }
        }
      }
    }
  }
}

Результат сопоставления:

    GET example_contact_purchases/_mapping
    {
  "example_contact_purchases": {
    "mappings": {
      "contact": {
        "dynamic": "false",
        "properties": {
          "country": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "purchases": {
            "type": "nested",
            "properties": {
              "uuid": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }
}

Создание первого элемента:

POST example_contact_purchases/contact
{
  "name" : "Fran",
  "country": "ES",
  "purchases" : [
    {
      "uuid" : "23"
    }
  ]
}

Создание второго элемента:

POST example_contact_purchases/contact
{
  "name" : "Jhon",
  "country": "UK",
  "purchases" : [
    {
      "uuid" : "45"
    }
  ]
}

Создание третьего элемента:

POST example_contact_purchases/contact
{
  "name" : "Leonardo",
  "country": "IT",
  "purchases" : [
    {
      "uuid" : "45"
    }
  ]
}

Пример запроса: Страна == ES И purchase.uuid == 23

GET example_contact_purchases/_search
{ 
   "query":{ 
      "filtered":{ 
         "query":{ 
            "query_string":{ 
               "query":"country:ES"
            }
         }
      }
   },
   "filter":{ 
      "nested":{ 
         "path":"purchases",
         "filter":{ 
            "query":{ 
               "query_string":{ 
                  "query":"(purchases.uuid:23)"
               }
            }
         }
      }
   }
}

Результат:

{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 1,
    "hits": [
      {
        "_index": "example_contact_purchases",
        "_type": "contact",
        "_id": "AW_nkURti9zva2kl7ESR",
        "_score": 1,
        "_source": {
          "name": "Fran",
          "country": "ES",
          "purchases": [
            {
              "uuid": "23"
            }
          ]
        }
      }
    ]
  }
}

Целевой запрос: Страна == "ES" ИЛИ purchase.uuid == 45

1 Ответ

2 голосов
/ 28 января 2020

Вы можете сделать это с помощью запроса bool. Ваш запрос будет выглядеть примерно так:

POST example_contact_purchases/contact/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "query_string": {
            "query": "country:ES"
          }
        },
        {
          "nested": {
            "path": "purchases",
            "filter": {
              "query": {
                "query_string": {
                  "query": "(purchases.uuid:45)"
                }
              }
            }
          }
        }
      ]
    }
  }
}

Обратите внимание, что should == OR в этом случае.

Кроме того, поскольку вы запрашиваете эти поля (country и purchases.uuid) по точному значению вы можете установить их как not_analyzed (или keyword в современных версиях Elasticsearch) и использовать запрос точного соответствия, например term.

Надеюсь, это поможет!

...