Создание запроса фильтра с помощью эластичного поиска

#elasticsearch

#elasticsearch

Вопрос:

Мне нужно создать запрос эластичного поиска для фильтрации из журналов, которые уже проиндексированы в индексе эластичного поиска.

Проблема заключается в том, что перечислены журналы пользователя, чья электронная почта ‘test@yopmail.com ‘ и является частью company_id ‘123’. Список журналов изменяется по мере добавления новых фильтров. Для экземпляра, журналы с проверкой события или проверкой или пользователи с температурным диапазоном между 28,7 — 37,8.

Эквивалентный запрос mysql :

 select * from logs
where
(
    company_id = 123 or company_id is null // company_id may be missing 
)
AND
(
    email = 'test@yopmail.com'
)
AND
(
    event = 'checkIn'
    or event = 'checkOut'
    or 
        (
            event = 'temperature'
            AND temperature >= 28.7
            AND temperature <= 37.8
        )
)

 

где logs — это имя индекса, company_id, email, событие, температура, create_date — имена полей (столбцов).

Сгенерированный мной запрос :

 'query' => {
    'bool' => {
        'must' => [            
            {
                'bool' => {
                    'must' => {
                        'match' => {
                            "email.keyword" => {
                                'query' => $email, 'fuzziness' => 'auto'
                            }
                        }
                    },
                    'should' => {
                        {
                            'match' => {
                                "event" => {
                                    'query' => "checkIn"
                                }
                            }
                        },
                        {
                            'match' => {
                                "event" => {
                                    'query' => "checkOut"
                                }
                            }
                        },
                        {
                            'range' => {
                                "temperature" => {
                                    "gte" => 28.7,
                                    "lte" => 37.8
                                }
                            }
                        }

                    }
                }
            {
        ],
        'should' => [
            {
                'bool' => {
                    'should' => [
                        {
                            'match' => {
                                "company_id" => [
                                    'query'     => $company_id
                                ]
                            }
                        }
                    ],
                    'must_not' => [
                        {
                            'exists' => {
                                'field' => 'company_id'
                            }
                        }
                    ]
                }
            }
        ]
    }
}
 

Но это работает не так, как должно.

Любая помощь здесь будет оценена. Спасибо

Ответ №1:

Ниже приведен запрос DSL, который соответствует вашему SQL-запросу. он немного отличается от того, который у вас есть.

 {
  "query": {
    "bool": {
      "filter": [
        {
          "bool": {
            "minimum_should_match": 1,
            "should": [
              {
                "term": {
                  "company_id": "123"
                }
              },
              {
                "bool": {
                  "must_not": {
                    "exists": {
                      "field": "company_id"
                    }
                  }
                }
              }
            ]
          }
        },
        {
          "term": {
            "email.keyword": "test@yopmail.com"
          }
        },
        {
          "bool": {
            "minimum_should_match": 1,
            "should": [
              {
                "terms": {
                  "event": ["checkIn", "checkOut"]
                }
              },
              {
                "bool": {
                  "filter": [
                    {
                      "term": {
                        "event": "temperature"
                      }
                    },
                    {
                      "range": {
                        "temperature": {
                          "gte": 28.7,
                          "lte": 37.8
                        }
                      }
                    }
                  ]
                }
              }
            ]
          }
        }
      ]
    }
  }
}