Elasticsearch查询分析

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

你可能感兴趣的:(分布式,数据库,综合)