[ElasticSearch2.x]Filter之Filter原理

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 1. ElasticSearch 2.0 变动1.1 Queries与filters合并查询(Queries)和过滤器(filters)进行合并 - 所有过滤器子句现在都是查询子句( all filter clauses are now query clauses.)。

1. ElasticSearch 2.0 变动

1.1 Queries与filters合并

查询(Queries)和过滤器(filters)进行合并 - 所有过滤器子句现在都是查询子句( all filter clauses are now query clauses.)。 相反,查询子句现在可以在查询上下文或过滤器上下文中使用:

Query context

在查询上下文中使用的查询将计算相关性分数,不会被缓存。 只要过滤器上下文不适用,就使用查询上下文。

Filter context

在过滤器上下文中使用的查询将不会计算相关性分数,并且可以缓存。 过滤器上下文由以下引入:

  • constant_score查询
  • bool查询中的must_not和(新添加)filter参数
  • function_score查询中的filterfilters参数
  • 任何叫filter的API,例如post_filter搜索参数,或者在聚合和索引别名中(any API called filter, such as the post_filter search parameter, or in aggregations or index aliases)

1.2 or 和 and通过bool实现

以前orand过滤器与bool过滤器有不同的执行模式。 (It used to be important to use and/or with certain filter clauses, and bool with others.)。

现在这个区别已被删除:现在bool查询足够智能,可以很好地处理这两种情况。 由于这种变化,现在orand过滤器是bool查询内部执行语法。 这些过滤器将来会被删除。

1.3 filtered查询 与 query过滤器 废弃

query过滤器已经废弃不再需要 - 所有查询都可以在查询或过滤器上下文中使用。

filtered查询已被弃用。 filtered查询如下:

GET _search
{
  "query": {
    "filtered": {
      "query": {
        "match": {
          "text": "quick brown fox"
        }
      },
      "filter": {
        "term": {
          "status": "published"
        }
      }
    }
  }
}

将查询和过滤器转换为bool查询中的mustfilter参数:

GET _search
{
  "query": {
    "bool": {
      "must": {
        "match": {
          "text": "quick brown fox"
        }
      },
      "filter": {
        "term": {
          "status": "published"
        }
      }
    }
  }
}

1.4 Filter自动缓存

以前可以通过_cache选项来控制哪些过滤器被缓存,并提供一个自定义的_cache_key。 这些选项已被弃用,如果存在,将被忽略。

过滤器上下文中使用的查询子句现在可以自动缓存。该算法考虑到使用频率,查询执行成本以及构建过滤器的成本。

terms过滤器查找机制不在缓存文档内容.现在依赖于文件系统缓存.如果查找索引不是太大,建议通过设置index.auto_expand_replicas:0-all将其复制到所有节点,以消除网络开销。

1.5 Java API Query和Filter重构

org.elasticsearch.index.queries.FilterBuilders从ElasticSearch2.0开始已被删除,作为查询和过滤器组合的一部分。 这些过滤器现在可以在QueryBuilders中使用具有相同名称的方法。所有可以接受FilterBuilder的方法现在也可以接受QueryBuilder。

以前使用方式:

FilterBuilders.boolFilter()  
    .must(FilterBuilders.termFilter("name", "张三"))  
    .mustNot(FilterBuilders.rangeFilter("age").from(28).to(30))  
    .should(FilterBuilders.termFilter("city", "北京"));

现在可以使用如下方式:

BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.termQuery("name", "张三"));
boolQueryBuilder.must(QueryBuilders.rangeQuery("age").from(28).to(30));
boolQueryBuilder.must(QueryBuilders.termQuery("city", "北京");
ConstantScoreQueryBuilder queryBuilder = QueryBuilders.constantScoreQuery(boolQueryBuilder);

2. 深入理解Filter

在执行非评分查询时,Elasticsearch内部会执行多个操作.以下面查询为例:

curl -XPUT  'localhost:9200/my_store/products/1' -d '{
"price" : 10, 
"productID" : "XHDK-A-1293-#fJ3"
}';

curl -XPUT  'localhost:9200/my_store/products/2' -d '{
"price" : 20, 
"productID" : "KDKE-B-9947-#kL5"
}';

curl -XPUT  'localhost:9200/my_store/products/3' -d '{
"price" : 30, 
"productID" : "JODL-X-1937-#pV7"
}';

curl -XPUT  'localhost:9200/my_store/products/4' -d '{
"price" : 40, 
"productID" : "QQPX-R-3956-#aD8"
}';

例如我们想要查询产品ID为XHDK-A-1293-#fJ3的产品:

curl -XGET 'localhost:9200/my_store/products/_search?pretty' -d'
{
    "query" : {
        "constant_score" : { 
            "filter" : {
                "term" : { 
                    "productID" : "XHDK-A-1293-#fJ3"
                }
            }
        }
    }
}
'

2.1 查找匹配文档

term查询在倒排索引中查找词条XHDK-A-1293-#fJ3,并检索包含该词条的所有文档。 在本例中,只有文件1具有我们正在寻找的词条。然后获取包含该 term 的所有文档。

2.2 构建bitset

然后,过滤器构建一个bitset - 一个包含1和0的数组,描述了哪些文档包含查找词条。 匹配文档的标志位是 1 。 在我们的例子中,bitset将是[1,0,0,0](只有文档1具有我们要查找的词条)。在内部,它表示成一个 "roaring bitmap",可以同时对稀疏或密集的集合进行高效编码。

2.3 迭代bitset(s)

一旦为每个查询生成了bitsets,Elasticsearch会遍历该bitsets,以找到满足所有过滤条件的匹配文档集合。 执行顺序是启发式的(The order of execution is decided heuristically),但通常最稀疏的bitsets是首先被迭代的(因为它排除了最大数量的文档)。

2.4 增加使用计数器

Elasticsearch 可以缓存非评分查询从而达到更快的访问,但是有一点不合理的地方是它也会缓存一些使用极少的东西。由于倒排索引的原因,非评分计算已经相当快了,所以我们只想缓存那些我们知道在后面会被再次使用的查询,以避免资源的浪费。

为了实现上面的目标,Elasticsearch 会跟踪每个索引查询使用的历史。如果查询在最近的 256 次查询中会被多次用到,那么就会被缓存到内存中。而当bitset被缓存时,对于具有少于10,000个文档(或小于总索引大小的3%)的段,会省略缓存。这些小的段即将会消失,所以为它们缓存是一种浪费。

实际情况并非如此(执行有点复杂,这取决于查询计划是如何重新规划的,有些启发式是基于查询代价的)(execution is a bit more complicated based on how the query planner re-arranges things, and some heuristics based on query cost),你可以在理论上认为非评分查询 先于 评分查询执行。非评分查询的目的是降低那些将高成本评分查询计算的文档数量,从而达到快速搜索的目的。

从概念上记住非评分计算是首先执行的,这将有助于写出高效又快速的搜索请求。

原文:https://www.elastic.co/guide/en/elasticsearch/guide/current/_finding_exact_values.html#_internal_filter_operation

https://www.elastic.co/guide/en/elasticsearch/reference/2.0/breaking_20_query_dsl_changes.html

https://www.elastic.co/guide/en/elasticsearch/reference/2.0/breaking_20_java_api_changes.html




相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
1月前
|
存储 搜索推荐 数据挖掘
ElasticSearch架构介绍及原理解析
ElasticSearch架构介绍及原理解析
90 0
|
3月前
|
自然语言处理 API 索引
Elasticsearch Analyzer原理分析并实现中文分词
Elasticsearch Analyzer原理分析并实现中文分词
73 0
|
8月前
|
存储 自然语言处理 负载均衡
|
5月前
|
存储 负载均衡 算法
分布式系列教程(36) -ElasticSearch集群原理
分布式系列教程(36) -ElasticSearch集群原理
44 0
|
7月前
|
存储 缓存 算法
ElasticSearch工作原理
ElasticSearch工作原理
57 0
|
9月前
|
存储 自然语言处理 负载均衡
八.全文检索ElasticSearch经典入门-深入理解ElasticSearch核心原理
八.全文检索ElasticSearch经典入门-深入理解ElasticSearch核心原理
|
9月前
|
自然语言处理 搜索推荐 关系型数据库
Elasticsearch搜索引擎原理理解通俗易懂
记得小马最早期刚参加工作的时候全文索引用的是Sphinx。 当一个功能需要对表中的text varchar等文本进行like查询时,MySQL全表扫描很慢,需要Sphinx。Sphinx能解决性能和中文分词问题。
104 1
Elasticsearch搜索引擎原理理解通俗易懂
|
9月前
|
自然语言处理 API 索引
Elasticsearch Analyzer原理分析并实现中文分词
Elasticsearch Analyzer原理分析并实现中文分词
108 0
|
10月前
|
存储 消息中间件 缓存
【ElasticSearch从入门到放弃系列 九】Elasticsearch原理机制探索
【ElasticSearch从入门到放弃系列 九】Elasticsearch原理机制探索
164 0
|
10月前
|
存储 JSON 运维
Elasticsearch的工作原理是什么?
Elasticsearch的工作原理是什么?
67 1
Elasticsearch的工作原理是什么?

热门文章

最新文章