2012-05-27 88 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.latlocation.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,你應該能夠指定mustshouldshould_not能得到相應的混合物和/或爲您的查詢。

+1

我認爲這是我嘗試的,上面的代碼片段。 – ahmedyha

0

可以使用QueryBuilders.multiMatchQuery代替QueryBuilders.termQuery