经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Elasticsearch » 查看文章
Elasticsearch Field Options Norms
来源:cnblogs  作者:hapjin  时间:2019/8/5 9:53:17  对本文有异议

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

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

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

  1. PUT my_index
  2. {
  3. "settings": {
  4. "number_of_shards": 1,
  5. "number_of_replicas": 0
  6. },
  7. "mappings": {
  8. "_doc": {
  9. "_source": {
  10. "enabled": true
  11. },
  12. "properties": {
  13. "title": {
  14. "type": "text",
  15. "norms": false
  16. },
  17. "overview": {
  18. "type": "text",
  19. "norms": true
  20. },
  21. "body": {
  22. "type": "text"
  23. },
  24. "author": {
  25. "type": "keyword",
  26. "norms": true
  27. },
  28. "chapters": {
  29. "type": "keyword",
  30. "norms": false
  31. },
  32. "email": {
  33. "type": "keyword"
  34. }
  35. }
  36. }
  37. }
  38. }

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 就倾向于给长度较小的字段打高分。

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算法给出的公式计算文档得分时,boosting就是 在计算过程中 进行某种 微调。

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 信息:

  1. GET my_index/_mapping
  2. {
  3. "my_index": {
  4. "mappings": {
  5. "_doc": {
  6. "properties": {
  7. "author": {
  8. "type": "keyword",
  9. "norms": true
  10. },
  11. "body": {
  12. "type": "text"
  13. },
  14. "chapters": {
  15. "type": "keyword"
  16. },
  17. "email": {
  18. "type": "keyword"
  19. },
  20. "overview": {
  21. "type": "text"
  22. },
  23. "title": {
  24. "type": "text",
  25. "norms": false
  26. }
  27. }
  28. }
  29. }
  30. }
  31. }

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

原文链接:http://www.cnblogs.com/hapjin/p/11254535.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号