2012-05-27 5 views
6

Учитывая JSON в индексе ES в следующем формате:Elasticsearch QueryBuilder Совпадение Множественные Условия

{ 
    "pin": { 
     "id": 123, 
     "location": { 
      "lat": 456, 
      "lon":-789 
     } 
    } 
} 

Следующая получает документ, совпадающий с id поле:

client.prepareSearch("index_name") 
     .setTypes("pin") 
     .setQuery(QueryBuilders.termQuery("id", 123)) 
     .execute() 
     .actionGet(); 

Вместо этого, я пытаюсь соответствовать несколько полей, т.е. (location.lat, location.lon).

QueryBuilders.termQuery(); // accepts only a single term 

Пробовал несколько вариантов, но ни один из них не похоже на работу, например:

QueryBuilder queryBuilder = QueryBuilders.boolQuery() 
     .must(QueryBuilders.termQuery("location.lat", 456)) 
     .must(QueryBuilders.termQuery("location.lon", -789)); 

client.prepareSearch("index_name") 
     .setTypes("pin") 
     .setQuery(queryBuilder) 
     .execute() 
     .actionGet(); 
+0

ли место индексироваться geo_point? – imotov

+0

Да, он отображается как 'geo_point'. – ahmedyha

ответ

4

По умолчанию поле geo_point не индексируется как два поля (location.lat и location.lon), оно индексируется как одно поле, которое содержит как широту, так и долготу.

Вы можете включить индексирование широты и долготы, включив lat_lonmapping option. Однако в вашем примере значения для широты и долготы слишком велики. Таким образом, они нормализуются, преобразуются в двойные и индексируются как -84.0 и -69.0 вместо 456 и -789. Итак, если вы включите lat_lon и замените значение в запросах, вы сможете получить результаты.

Обратите внимание, что значения для широты и долготы перед индексацией преобразуются в двойные. Поэтому использование терминальных запросов может оказаться не очень практичным в долгосрочной перспективе, поскольку вам придется всегда учитывать ошибки округления. Возможно, было бы более полезно использовать range queries или elasticsearch geospatial queries.

1

Отъезд bool query в ElasticSearch, вы должны быть в состоянии указать must, should или should_not, чтобы получить соответствующую смесь и/или для вашего запроса.

+1

Я думаю, что это то, что я пробовал, фрагмент кода выше. – ahmedyha

0

Вы можете использовать QueryBuilders.multiMatchQuery вместо QueryBuilders.termQuery

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