一,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