2016-07-05 2 views
1

У меня есть индекс с 2-х полей и некоторых документов, например, следующее:Elasticsearch агрегат по нескольким полям отдельно

city    team 
========================================= 
New York   New York Knicks 
New York   Brooklyn Nets 
New Orleans   New Orleans Pelicans 

Моя цель состоит в том, чтобы обеспечить automplete, который выполняет поиск на обоих полях, как это:

Query: [ new     ] 
     +----------------------+ 
     |  Cities   | 
     +----------------------+ 
     | New York    | 
     | New Orleans   | 
     +----------------------| 
     |  Teams   | 
     +----------------------| 
     | New York Knicks  | 
     | New Orleans Pelicans | 
     +----------------------+ 

Мой запрос для фильтрации документов достаточно прост:

"query": { 
    "bool": { 
     "should": [ 
      { 
       "match_phrase_prefix": { 
        "city": "new" 
       } 
      }, 
      { 
       "match_phrase_prefix": { 
        "team": "new" 
       } 
      } 
     ] 
    } 
} 

Однако я У меня проблемы с агрегатами. Мой первый подход:

"aggs": { 
    "city": { 
     "terms": { 
      "field": "city.raw" 
     } 
    }, 
    "team": { 
     "terms": { 
      "field": "team.raw" 
     } 
    } 
} 

(raw является not_analyzed копией полей для целей агрегации)

Это не сработало, потому что Brooklyn Nets была включена в результаты - и это не должно:

"aggregations": { 
    "city": { 
     "doc_count_error_upper_bound": 0, 
     "sum_other_doc_count": 0, 
     "buckets": [ 
      { 
       "key": "New York", 
       "doc_count": 2 
      }, 
      { 
       "key": "New Orleans", 
       "doc_count": 1 
      } 
     ] 
    }, 
    "team": { 
     "doc_count_error_upper_bound": 0, 
     "sum_other_doc_count": 0, 
     "buckets": [ 
      { 
       "key": "Brooklyn Nets", 
       "doc_count": 1 
      }, 
      { 
       "key": "New Orleans Pelicans", 
       "doc_count": 1 
      }, 
      { 
       "key": "New York Knicks", 
       "doc_count": 1 
      } 
     ] 
    } 
} 

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

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

ответ

1

Вам необходима агрегация фильтра для фильтрации документов, которые будут агрегатироваться в соответствии с вашими фильтрами в самом запросе:

"aggs": { 
    "city": { 
     "filter": { 
     "bool": { 
      "must": [ 
      { 
       "query": { 
       "match_phrase_prefix": { 
        "city": "new" 
       } 
       } 
      } 
      ] 
     } 
     }, 
     "aggs": { 
     "cities": { 
      "terms": { 
      "field": "city.raw" 
      } 
     } 
     } 
    }, 
    "team": { 
     "filter": { 
     "bool": { 
      "must": [ 
      { 
       "query": { 
       "match_phrase_prefix": { 
        "team": "new" 
       } 
       } 
      } 
      ] 
     } 
     }, 
     "aggs": { 
     "cities": { 
      "terms": { 
      "field": "team.raw" 
      } 
     } 
     } 
    } 
    } 
+0

Отлично, это сработало! Большое спасибо! – stefanobaldo

0

запроса,

"query": { 
    "bool": { 
     "should": [ 
      { 
       "match_phrase_prefix": { 
        "city": "new" 
       } 
      }, 
      { 
       "match_phrase_prefix": { 
        "team": "new" 
       } 
      } 
     ] 
    } 
} 

возвращает документ с «Городом: New Йорк Команда: Brooklyn Nets "в результатах. Потому что поле «город» имеет префикс «новый», хотя в поле «команда» нет.

Я думаю, что когда вы используете скопления, с ним подсчитывается документ с «Город: Нью-Йоркская команда: Бруклинские сети». Документ «Команда: Brooklyn Nets» включен в результирующий набор запроса из-за «Сити: Нью-Йорк», и он подсчитывается в ведрах.

Комплект minimum_should_match до 2, если вы хотите это проверить.

+0

Спасибо вам за ваш ответ, но это мне не помогло. – stefanobaldo

Смежные вопросы