Elasticsearch многослойный фильтр

Я довольно новичок в Elasticsearch, так что вот мой вопрос. Я хочу сделать поисковый запрос сластиком поиска и хочу фильтр с несколькими терминами.

Если я хочу найти пользователя 'tom', то я бы хотел, чтобы все совпадения были такими, где пользователь 'isActive = 1', 'isPrivate = 0' и 'isOwner = 1'.

Вот мой поисковый запрос

"query":{
    "filtered": {
        "query": {
            "query_string": {
                "query":"*tom*",
                "default_operator": "OR",
                "fields": ["username"]
            }
        },
        "filter": {
            "term": { 
                "isActive": "1",
                "isPrivate": "0",
                "isOwner": "1"
            }
        }
    }
}   

Когда я использую 2 термина, это работает как шарм, но когда я использую 3 термина, это не так.

Спасибо за помощь!!

1 ответ

Решение

Вы должны использовать bool filter в AND все ваши условия:

"query":{
    "filtered": {
        "query": {
            "query_string": {
                "query":"*tom*",
                "default_operator": "OR",
                "fields": ["username"]
            }
        },
        "filter": {
            "bool" : {
                "must" : [
                    {"term" : { "isActive" : "1" } },
                    {"term" : { "isPrivate" : "0" } },
                    {"term" : { "isOwner" : "1" } }
                ]
             }
         }
     }
}   

Как говорится в одном из комментариев, синтаксис изменился в последних версиях ES. Если вы используете Elasticsearch 6.+ и хотите использовать подстановочный знак и последовательность терминов в своем запросе (например, в вопросе), вы можете использовать что-то вроде этого:

GET your_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "wildcard": {
            "your_field_name_1": {
              "value": "tom*"
            }
          }
        },
        {
          "term": {
            "your_field_name_2": {
              "value": "US"
            }
          }
        },
        {
          "term": {
            "your_field_name_3": {
              "value": "Michigan"
            }
          }
        },
        {
          "term": {
            "your_field_name_4": {
              "value": "0"
            }
          }
        }
      ]
    }
  }
}

Также из документации о подстановочных запросах:

Обратите внимание, что этот запрос может быть медленным, поскольку он должен повторяться по многим терминам. Чтобы предотвратить чрезвычайно медленные запросы с подстановочными знаками, термин с подстановочными знаками не должен начинаться с одного из подстановочных знаков * или?.

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

Другие вопросы по тегам