Elasticsearch 定义字段时Norms选项的作用

本文介绍ElasticSearch中2种字段(text 和 keyword)的Norms参数作用。

创建ES索引时,一般指定2种配置信息:settings、mappings。settings 与数据存储有关(几个分片、几个副本);而mappings 是数据模型,类似于MySQL中的表结构定义。在Mapping信息中指定每个字段的类型,ElasticSearch支持多种类型的字段(field datatypes),比如String、Numeric、Date…其中String又细分成为种:keyword 和 text。在创建索引时,需要定义字段并为每个字段指定类型,示例如下:

PUT my_index
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
},
"mappings": {
"_doc": {
"_source": {
"enabled": true
},
"properties": {
"title": {
"type": "text",
"norms": false
},
"overview": {
"type": "text",
"norms": true
},
"body": {
"type": "text"
},
"author": {
"type": "keyword",
"norms": true
},
"chapters": {
"type": "keyword",
"norms": false
},
"email": {
"type": "keyword"
}
}
}
}
}

my_index 索引的 title 字段类型是 text,而 author 字段类型是 keyword。

对于 text 类型的字段而言,默认开启了norms,而 keyword 类型的字段则默认关闭了norms

Whether field-length should be taken into account when scoring queries. Accepts true(text filed datatype) or false(keyword filed datatype)

为什么 keyword 类型的字段默认关闭 norms 呢?keyword 类型的string 可理解为:Do index the field, but don't analyze the string value,也即:keyword 类型的字段是不会被Analyzer "分析成" 一个个的term的,它是一个single-token fields,因此也就不需要字段长度(fieldNorm)、tfNorm(term frequency Norm)这些归一化因子了。而 text 类型的字段会被分析器(Analyzer)分析,生成若干个terms,两个 text 类型的字段,一个可能有很多term(比如文章的正文),另一个只有很少的term(比如文章的标题),在多字段查询时,就需要长度归一化,这就是为什么 text 类型字段默认开启 norms 选项的原因吧。另外,对于Lucene常用的2种评分算法:tf-idf 和 bm25,tf-idf 就倾向于给长度较小的字段打高分,为什么呢?Lucene 的相似度评分公式,主要由三部分组成:IDF score,TF score 还有 fieldNorms。就TF-IDF评分公式而言,IDF score 是log(numDocs/(docFreq+1)),TF score 是 sqrt(tf),fieldNorms 是 1/sqrt(length),因此:文档长度越短,fieldNorms越大,评分越高,这也是为什么TF-IDF严重偏向于给短文本打高分的原因。

norms 作用是什么?

norms 是一个用来计算文档/字段得分(Score)的"调节因子"。TF-IDF、BM25算法计算文档得分时都用到了norms参数,具体可参考这篇文章中的Lucene文档得分计算公式。

ElasticSearch中的一篇文档(Document),里面有多个字段。查询解析器(QueryParser)将用户输入的查询字符串解析成Terms ,在多字段搜索中,每个 Term 会去匹配各个字段,为每个字段计算一个得分,各个字段的得分经过某种方式(以词为中心的搜索 vs 以字段为中心的搜索)组合起来,最终得到一篇文档的得分。

ES官方文档关于Norms解释:

Norms store various normalization factors that are later used at query time in order to compute the score of a document relatively to a query.

这里的 normalization factors 用于查询计算文档得分时进行 boosting。比如根据BM25算法给出的公式(freq*(k1+1))/(freq+k1*(1-b+b*fieldLength/avgFieldLength))计算文档得分时,其中的fieldLength/avgFieldLength就是 normalization factors。

norms 的代价

开启norms之后,每篇文档的每个字段需要一个字节存储norms。对于 text 类型的字段而言是默认开启norms的,因此对于不需要评分的 text 类型的字段,可以禁用norms,这算是一个调优点吧。

Although useful for scoring, norms also require quite a lot of disk (typically in the order of one byte per document per field in your index, even for documents that don’t have this specific field). As a consequence, if you don’t need scoring on a specific field, you should disable norms on that field

norms 因子属于 Index-time boosting一部分,也即:在索引文档(写入文档)的时候,就已经将所有boosting因子存储起来,在查询时从内存中读取,参与得分计算。参考《Lucene in action》中一段话:

During indexing, all sources of index-time boosts are combined into a single floating point number for each indexed field in the document. The document may have its own boost; each field may have a boost; and Lucene computes an automatic boost based on the number of tokens in the field (shorter fields have a higher boost). These boosts are combined and then compactly encoded (quantized) into a single byte, which is stored per field per document. During searching, norms for any field being searched are loaded into memory, decoded back into a floating-point number, and used when computing the relevance score.

另一种类型的 boosting 是search time boosting,在查询语句中指定boosting因子,然后动态计算出文档得分,具体可参考:《relevant search with applications for solr and elasticsearch》,本文不再详述。但是值得注意的是:目前的ES版本已经不再推荐使用index time boosting了,而是推荐使用 search time boosting。ES官方文档给出的理由如下:

  • 在索引文档时存储的boosting因子(开启 norms 选项),一经存储,就无法改变。要想改变,只能reindex索引
  • search time boosting 的效果和 index time boosting是一样的,并且search time boosting能够动态指定boosting因子(但计算文档得分时更消耗CPU吧),灵活性更大。而index time boosting需要额外的存储空间
  • index time boosting因子存储在norms字段,它影响了 field length normalization,从而导致文档相似度计算结果不太准确(lower quality relevance calculations)

附:my_index索引的mapping 信息:

GET my_index/_mapping

{
"my_index": {
"mappings": {
"_doc": {
"properties": {
"author": {
"type": "keyword",
"norms": true
},
"body": {
"type": "text"
},
"chapters": {
"type": "keyword"
},
"email": {
"type": "keyword"
},
"overview": {
"type": "text"
},
"title": {
"type": "text",
"norms": false
}
}
}
}
}
}

原文:https://www.cnblogs.com/hapjin/p/11254535.html

Elasticsearch Field Options Norms的更多相关文章

  1. Django model中常见Field types , Field options

    AutoField :自增,数据库 BooleanField:布尔型 CharField:字符型 DateField:日期,datetime.date类的实例.有两个常用的option,auto_no ...

  2. Django文档——Model字段选项(Field Options)

    建立一个简易Model class Person(models.Model): GENDER_CHOICES=( (1,'Male'), (2,'Female'), ) name=models.Cha ...

  3. Django之 Model Field Options

    以下这些选项都是可选择的,非固定要求. 1)null,注意在CharField或者TextField里避免使用null,因为其存储的值是空字符串而不是NULL 2)blank该字段是否可以为空.如果为 ...

  4. ElasticSearch+Logstash+Filebeat+Kibana集群日志管理分析平台搭建

    一.ELK搜索引擎原理介绍 在使用搜索引擎是你可能会觉得很简单方便,只需要在搜索栏输入想要的关键字就能显示出想要的结果.但在这简单的操作背后是搜索引擎复杂的逻辑和许多组件协同工作的结果. 搜索引擎的组 ...

  5. ELK & ElasticSearch 5.1 基础概念及配置文件详解【转】

    转自:https://blog.csdn.net/zxf_668899/article/details/54582849 配置文件 基本概念 接近实时NRT 集群cluster 索引index 文档d ...

  6. elasticsearch配置详解

    一.说明 使用的是新版本5.1,直接从官网下载rpm包进行安装,https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5 ...

  7. ELK集群之elasticsearch(3)

    Elasticsearch-基础介绍及索引原理分析 介绍 Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引 ...

  8. 【转】Django Model field reference学习总结

    Django Model field reference学习总结(一) 本文档包含所有字段选项(field options)的内部细节和Django已经提供的field types. Field 选项 ...

  9. Django Model field reference

    ===================== Model field reference ===================== .. module:: django.db.models.field ...

随机推荐

  1. http协议历史

    HTTP 通常被译为超文本传输协议, 但这种译法并不严谨. 严谨的译名应该为“超文本转移协议”. 最初设想的基本理念是: 借助多文档之间相互关联形成的超文本( HyperText) , 连成可相互参阅 ...

  2. IntelliJ IDEA 中使用 Lambok (注解无效问题的解决)

    一,概述 Lambok可以说一个能很大提高开发效率的插件,只要在使用注解的方式就能实现很多常用的功能.如常用的@Data能在编译阶段自动生成toString方法,getter方法setter方法等. ...

  3. OPC 集成的五大要素,你都掌握了吗?

    相信在处理工业项目集成问题的时候,自动化集成供应商真正需要的不是那些华丽的宣传语,而是提供真正的通信数据集成实力. 任何自动化集成的供应商都希望能够消除中间的层层障碍,从而实现真正的信息集成互通.那么 ...

  4. iOS开发之--iPhone X 适配:MJRefresh上拉加载适配

    问题如下图: 出现原因,phoneX系列手机下方多了34像素的工作区域,所以需要对x全系列手机坐下适配, 解决如下: self.tableView.mj_footer.ignoredScrollVie ...

  5. jmeter中websocket接口测试

    一.Websocket协议简介 Websocket是一个持久化的协议,相对于HTTP这种非持久的协议来说: HTTP协议: HTTP的生命周期通过 Request 来界定,也就是一个 Request  ...

  6. numpy,matplotlib,pandas

    目录 numpy模块 numpy简介 numpy使用 matplotlib模块 条形图 直方图 折线图 散点图+直线图 pandas模块 numpy模块 numpy简介 numpy官方文档:https ...

  7. ansible服务部署

    1.ansible.cfg配置文件 [defaults] #inventory= /home/op/ansible/testing #sudo_user=root remote_port=9122 r ...

  8. Tests in error:BlogApplicationTests.initializationError » IllegalState Unable to find a @Spri...【解决】

    刚刚写完一个项目,准备打包,却发现无法打包. 然后认真排查了一下问题.发现少引入了一个插件. <plugin> <groupId>org.apache.maven.plugin ...

  9. docker容器网络—单主机容器网络

    当我们在单台物理机或虚拟机中运行多个docker容器应用时,这些容器之间是如何进行通信的呢,或者外界是如何访问这些容器的? 这里就涉及了单机容器网络相关的知识.docker 安装后默认 情况下会在宿主 ...

  10. Spring Boot中以代码方式配置Tomcat

    在Spring Boot2.0以上配置嵌入式Servlet容器时EmbeddedServletContainerCustomizer类不存在,经网络查询发现被WebServerFactoryCusto ...