Как использовать параметры запроса ElasticSearch (запрос DSL) для нескольких типов?

Я работаю с ElasticSearch с последних нескольких месяцев, но все еще считаю это сложным, когда мне приходится передавать сложный запрос.

Я хочу запустить запрос, который будет искать несколько "типов", и каждый тип нужно искать с помощью собственных "фильтров", но для этого нужно объединить "результаты поиска"

Например:

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

ИЛИ

Запрос, в котором есть предложение "И" и "НЕ"

Пример запроса:

$options['query'] = array(
        'query' => array(
            'filtered' => array(
                'query' => array(
                    'query_string' => array(
                        'default_field' => 'name',
                        'query' => $this->search_term . '*',
                    ),
                ),
                'filter' => array(
                    'and' => array(
                        array(
                            'term' => array(
                                'access_id' => 2,
                            ),
                        ),
                    ),

                    'not' => array(
                        array(
                            'term' => array(
                                'follower' => 32,
                            ),
                        ),

                        array(
                            'term' => array(
                                'fan' => 36,
                            ),
                        ),
                    ),
                ),
            ),
        ),
    );

поскольку этот запрос предназначен для поиска пользователя с access_id = 2, но не должен иметь следящего элемента id 32 и вентилятора id 36

но это не работает.

Изменить: Измененный запрос

{
  "query": {
    "filtered": {
      "filter": {
        "and": [
          {
            "not": {
              "filter": {
                "and": [
                  {
                    "query": {
                      "query_string": {
                        "default_field": "fan",
                        "query": "*510*"
                      }
                    }
                  },
                  {
                    "query": {
                      "query_string": {
                        "default_field": "follower",
                        "query": "*510*"
                      }
                    }
                  }
                ]
              }
            }
          },
          {
            "term": {
              "access_id": 2
            }
          }
        ]
      },
      "query": {
        "field": {
          "name": "xyz*"
        }
      }
    }
  }
}

теперь, после выполнения этого запроса, я получаю два результата: один с последователем: "34,518" и вентилятор: "510", а второй с вентилятором: "34", но разве он не должен быть только вторым в результат.

Любые идеи?

Ответы

Ответ 1

Вы можете посмотреть слайды презентации, которую я дал в этом месяце, что объясняет основы работы DSL-запроса:

Условия ласки - объяснение DSL запроса ElasticSearch

Проблема с вашим запросом заключается в том, что ваши фильтры вложены неправильно. Фильтры and и not находятся на одном уровне, но фильтр not должен находиться под and:

curl -XGET 'http://127.0.0.1:9200/_all/_search?pretty=1'  -d '
{
   "query" : {
      "filtered" : {
         "filter" : {
            "and" : [
               {
                  "not" : {
                     "filter" : {
                        "and" : [
                           {
                              "term" : {
                                 "fan" : 36
                              }
                           },
                           {
                              "term" : {
                                 "follower" : 32
                              }
                           }
                        ]
                     }
                  }
               },
               {
                  "term" : {
                     "access_id" : 2
                  }
               }
            ]
         },
         "query" : {
            "field" : {
               "name" : "keywords to search"
            }
         }
      }
   }
}
'

Ответ 2

Я просто попробовал его с помощью "BOOL"

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "access_id": 2
          }
        },
        {
          "wildcard": {
            "name": "xyz*"
          }
        }
      ],
      "must_not": [
        {
          "wildcard": {
            "follower": "*510*"
          }
        },
        {
          "wildcard": {
            "fan": "*510*"
          }
        }
      ]
    }
  }
}

Он дает правильный ответ.

но я не уверен, что он будет использоваться так?