Как объединить многострочный запрос в фильтре Elasticsearch - PullRequest
0 голосов
/ 18 февраля 2020

В настоящее время я ищу создание фильтра Elasticsearch (для моего запроса) для фильтрации моего запроса, но он не работает, потому что фильтр также не фильтрует.

Версия кластера ES - 6.8.3. Вот мой текущий код фильтра (PHP версия):

'filter' => [
     ['term' => 
            [
                                'displayMode' => 'hidden'
                            ]],
                            [ 'bool' => [
                                'must_not' => [
                                    [ 'bool' => [
                                        'must' => [
                                            'term' => ['displayMode' => 'untreated']
                                        ]
                                    ]],
                                    [ 'bool' => [
                                        'must' => [
                                            'term' => [ 'lifetime' => 'temporary' ]
                                        ]
                                    ]]
                                ]]
                            ],
                            [ 'bool' => [
                                'must' => [
                                    [ 'bool' => [
                                        'must_not' => [
                                            'term' => ['activity' => 'inactive']
                                        ]
                                    ]],
                                    [ 'bool' => [
                                        'must_not' => [
                                            'term' => [ 'lifetime' => 'everlasting' ]
                                        ]
                                    ]],
                                    [ 'bool' => [
                                        'should' => [
                                            [ 'range' => [
                                                'toDate' => [
                                                    'lt' => (new \DateTime())->format('Y-m-d')
                                                ]
                                            ]],
                                            [ 'bool' => [
                                                'must_not' => [
                                                    'exists' => [
                                                        'field' => 'toDate'
                                                    ]
                                                ]
                                            ]]
                                        ]
                                    ]]
                                ]
                            ]]
      ]

Итак, чтобы отобразить элемент, вы должны соблюдать все эти условия:

item.displayAll != 'hidden'

И

(item.displayMode != 'untreated' AND item.lifetime != 'temporary')

И ТАКЖЕ

(item.activity != 'inactive' AND item.lifetime != 'everlasting' AND item.toDate < NOW())

К сожалению, мои условия "multi" условия не являются multi, поэтому каждый из вспомогательных фильтров, кажется, выполняется один за другим. Поэтому, если мой элемент «не обработан», но его «время жизни» отличается от «временного», элемент фильтруется, но это не должно быть.

РЕДАКТИРОВАТЬ: Когда я пытаюсь упростить мой фильтр (просто для проверки если маленький работает) он также не работает ...

// ...
'filter' => [
                                ['bool' => [
                                    'must_not' => [
                                        ['term' => [ 'displayMode' => 'untreated' ]],
                                        ['term' => [ 'lifetime' => 'temporary' ]]
                                    ]
                                ]],
   // ...

ИЛИ

'filter' => [
                                ['bool' => [
                                    'must' => [
                                        ['bool' => [
                                            'must_not' => [
                                                ['term' => [ 'displayMode' => 'untreated' ]],
                                            ]
                                        ]],
                                        ['bool' => [
                                            'must_not' => [
                                                ['term' => [ 'lifetime' => 'temporary' ]]
                                            ]
                                        ]]
                                    ]
                                ]],

(два приведенных выше примера не работают, потому что он фильтрует все результаты, даже действительные из них)

ИЛИ

'filter' => [
                                ['bool' => [
                                    'should' => [
                                        ['bool' => [
                                            'must_not' => [
                                                ['term' => [ 'displayMode' => 'untreated' ]],
                                            ]
                                        ]],
                                        ['bool' => [
                                            'must_not' => [
                                                ['term' => [ 'lifetime' => 'temporary' ]]
                                            ]
                                        ]]
                                    ]
                                ]],

(Пример выше, он не фильтрует ничего, как я хотел).

ИЛИ

'filter' => [
                                ['bool' => [
                                    'must_not' => [
                                        ['term' => [ 'displayMode' => 'untreated' ]],
                                        ['term' => [ 'lifetime' => 'temporary' ]]
                                    ]
                                ]]

То же самое, он фильтрует все результаты ..

Может кто-нибудь может мне помочь, пожалуйста?

Ответы [ 2 ]

1 голос
/ 18 февраля 2020

Таким образом, согласно вашей логической логике c, вы можете просто преобразовать это в bool запросы:

  • AND => filter
  • OR => should
  • != => must_not

Это даст:

{
  "query": {
    "bool": {
      "minimum_should_match": 1,
      "should": [
        {
          "bool": {
            "must_not": {
              "term": {
                "displayMode": "hidden"
              }
            }
          }
        },
        {
          "bool": {
            "must_not": [
              {
                "term": {
                  "displayMode": "untreated"
                }
              },
              {
                "term": {
                  "lifetime": "temporary"
                }
              }
            ]
          }
        },
        {
          "bool": {
            "must_not": [
              {
                "term": {
                  "activity": "inactive"
                }
              },
              {
                "term": {
                  "lifetime": "everlasting"
                }
              },
              {
                "bool": {
                  "should": [
                    {
                      "range": {
                        "toDate": {
                          "lt": "now"
                        }
                      }
                    },
                    {
                      "bool": {
                        "must_not": {
                          "exists": {
                            "field": "toDate"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            ]
          }
        }
      ]
    }
  }
}
0 голосов
/ 20 февраля 2020

Итак, после огромной траты времени я наконец понял, что мой индекс не содержит поля «время жизни». Все условия фильтров были не выполнены для этого. Мой первый запрос был хорошим (или одним из способов сделать то, что я хотел сделать). Хорошего дня.

...