Elasticsearch查詢分析
阿新 • • 發佈:2019-02-11
一,elasticsearch查詢分為query查詢和filter查詢兩種方式。
query查詢過程:
1,比較查詢條件;
2,然後計算分值,最後返回文件結果。
這種查詢方式適合於全文檢索類的查詢。
filter查詢
1,判斷是否滿足查詢條件,如果不滿足,會快取查詢過程(記錄該文件不滿足結果);
2,滿足的話,就直接快取結果。
這種查詢方式適合於精確值匹配方式的查詢。
綜上所述,filter快在兩個方面:
1 對結果進行快取;
2 避免計算文件相關性分值。
二,filter的型別。
但是這裡需要注意的是filter也分為兩種型別的filter:post_filter和filtered
post_filter(先查詢再過濾)
{
"query": {
"match":{"title":"cat"}
},
"post_filter":{
"term":{"year":1999}
}
}
即上面的查詢過程為:先按照"match":{"title":"cat"} 進行匹配查詢,然後對結果進行過濾。這樣這種filter不會提高效能。
filtered(先過濾再查詢,速度快)
{
"query": {
"filtered": {
"query": {
"match": {
"title": "cat"
}
},
"filter": {
"term": {
"year": 1999
}
}
}
}
}
上面的查詢過程為:
1,先按照
"filter": {
"term": {
"year": 1999
}
}
進行過濾,注意針對這個filter的查詢結果進行快取,同時也不計算文件的相關性分值。
2,再按照
"query": {
"match": {
"title": "cat"
}
}
對第一步中的過濾結果再進行query查詢。
看到上面的這種複雜的方式那麼為什麼不全部使用效率更高的filter查詢呢,例如下面這樣?
{
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"title": "cat"
}
},
{
"term": {
"year": 1999
}
}
]
}
}
}
}
}
這是因為:
1,這樣的話即保證了query查詢的特性;
2,又沒有浪費filter快取,當然如果這個內容沒必要快取的話也就沒畢業使用query了。
api使用,本來沒想寫過java api方面的內容,但是發現es至少在這裡做的還是比較隱晦的,找了好久才找到在哪裡,最開始一度還誤導filter和post filter是一樣的
//FilteredQueryBuilder qbuilder = QueryBuilders.filteredQuery(QueryBuilders.boolQuery(),filterBuilder);
//第一個引數是設定query,第二個引數是設定filter
FilteredQueryBuilder qbuilder = QueryBuilders.filteredQuery(null,filterBuilder);
SearchRequestBuilder request = client.prepareSearch(Config.getString("dong.es.index"))
.setSearchType(SearchType.COUNT)
.setTypes(Config.getString("dong.es.type"))
.setQuery(qbuilder);
注意上面的方式在2.2版本被廢棄呼叫,改用bool的方式
{
"query": {
"bool": {
"must": {
"match": {
"title": "cat"
}
},
"filter": {
"term": {
"year": 1999
}
}
}
}
}
除了上面提到的filtered過濾和post_filter過濾這兩種過濾方式之外,有時候還會看到過另外一種過濾方式filter outside過濾方式,如下面的case2:
Case 1:
{
"query": {
"filtered": {
"filter": {
"prefix": {
"name": "blah"
}
},
"query": {
"term": {
"dept": "engineering"
}
}
}
}
}
AND,
Case 2:
{
"query": {
"term": {
"dept": "engineering"
}
},
"filter": {
"prefix": {
"name": "blah"
}
}
}
不過我並沒有用過這種方式,這裡也就不深究了,不過網上簡單查了一下資料為:
1,case2和post_filter的查詢過程基本一樣,也是事後過濾;
2,case這種方式可能應用於facts裡面或者是Aggregations裡 。。。。。。。
3,網上的資料:
http://stackoverflow.com/questions/28958882/elasticsearch-filtered-query-vs-filter
http://elasticsearch-users.115913.n3.nabble.com/Filtered-query-vs-using-filter-outside-td3960119.html
參考資料:
es原始碼
https://segmentfault.com/a/1190000004429689
http://udn.yyuap.com/doc/mastering-elasticsearch/chapter-2/27_README.html
query查詢過程:
1,比較查詢條件;
2,然後計算分值,最後返回文件結果。
這種查詢方式適合於全文檢索類的查詢。
filter查詢
1,判斷是否滿足查詢條件,如果不滿足,會快取查詢過程(記錄該文件不滿足結果);
2,滿足的話,就直接快取結果。
這種查詢方式適合於精確值匹配方式的查詢。
綜上所述,filter快在兩個方面:
1 對結果進行快取;
2 避免計算文件相關性分值。
二,filter的型別。
但是這裡需要注意的是filter也分為兩種型別的filter:post_filter和filtered
post_filter(先查詢再過濾)
{
"query": {
"match":{"title":"cat"}
},
"post_filter":{
"term":{"year":1999}
}
}
即上面的查詢過程為:先按照"match":{"title":"cat"} 進行匹配查詢,然後對結果進行過濾。這樣這種filter不會提高效能。
filtered(先過濾再查詢,速度快)
{
"query": {
"filtered": {
"query": {
"match": {
"title": "cat"
}
},
"filter": {
"term": {
"year": 1999
}
}
}
}
}
上面的查詢過程為:
1,先按照
"filter": {
"term": {
"year": 1999
}
}
進行過濾,注意針對這個filter的查詢結果進行快取,同時也不計算文件的相關性分值。
2,再按照
"query": {
"match": {
"title": "cat"
}
}
對第一步中的過濾結果再進行query查詢。
看到上面的這種複雜的方式那麼為什麼不全部使用效率更高的filter查詢呢,例如下面這樣?
{
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"title": "cat"
}
},
{
"term": {
"year": 1999
}
}
]
}
}
}
}
}
這是因為:
1,這樣的話即保證了query查詢的特性;
2,又沒有浪費filter快取,當然如果這個內容沒必要快取的話也就沒畢業使用query了。
api使用,本來沒想寫過java api方面的內容,但是發現es至少在這裡做的還是比較隱晦的,找了好久才找到在哪裡,最開始一度還誤導filter和post filter是一樣的
//FilteredQueryBuilder qbuilder = QueryBuilders.filteredQuery(QueryBuilders.boolQuery(),filterBuilder);
//第一個引數是設定query,第二個引數是設定filter
FilteredQueryBuilder qbuilder = QueryBuilders.filteredQuery(null,filterBuilder);
SearchRequestBuilder request = client.prepareSearch(Config.getString("dong.es.index"))
.setSearchType(SearchType.COUNT)
.setTypes(Config.getString("dong.es.type"))
.setQuery(qbuilder);
注意上面的方式在2.2版本被廢棄呼叫,改用bool的方式
{
"query": {
"bool": {
"must": {
"match": {
"title": "cat"
}
},
"filter": {
"term": {
"year": 1999
}
}
}
}
}
除了上面提到的filtered過濾和post_filter過濾這兩種過濾方式之外,有時候還會看到過另外一種過濾方式filter outside過濾方式,如下面的case2:
Case 1:
{
"query": {
"filtered": {
"filter": {
"prefix": {
"name": "blah"
}
},
"query": {
"term": {
"dept": "engineering"
}
}
}
}
}
AND,
Case 2:
{
"query": {
"term": {
"dept": "engineering"
}
},
"filter": {
"prefix": {
"name": "blah"
}
}
}
不過我並沒有用過這種方式,這裡也就不深究了,不過網上簡單查了一下資料為:
1,case2和post_filter的查詢過程基本一樣,也是事後過濾;
2,case這種方式可能應用於facts裡面或者是Aggregations裡 。。。。。。。
3,網上的資料:
http://stackoverflow.com/questions/28958882/elasticsearch-filtered-query-vs-filter
http://elasticsearch-users.115913.n3.nabble.com/Filtered-query-vs-using-filter-outside-td3960119.html
參考資料:
es原始碼
https://segmentfault.com/a/1190000004429689
http://udn.yyuap.com/doc/mastering-elasticsearch/chapter-2/27_README.html