es:http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/analysis-intro.html
下一页:http://my.oschina.net/qiangzigege/blog/269856
内容
什么叫分析过程? 1)将文本块分词,以倒排索引的方式 2)归一化到标准形式来提高可搜索性。 这个工作的执行者叫做分析器,一个分析器包含以下3个功能: 1)字母过滤 首先,字符串依次通过任何一个字符过滤器, 过滤器的工作是清洗字符串,也就是说先清洗再分词。 一个字符过滤器可以去除HTML字符,也可以转换"&"变为"and". 2)分词 下一步,字符串被分词为很多个单词,一个简单的分词器也许依靠空格或者标点符号来分词。 3)单词过滤 最后,每个单词传给单词过滤器,它们可以将单词小写或者删除单词比如a,and,the,etc. 或者增加单词比如jump和leap. es提供了很多字符串过滤器,分词器和单词过滤器。 这些单元可以组合起来使用,后面再说。 内置的分析器 尽管如此,es也包含了很多内置的分词器,你可以直接使用。 我们列举了最重要的一些,演示区别。 所用的文本基于: "Set the shape to semi-transparent by calling set_trans(5)" 标准分析器 标准分析器是es默认的分析器,如果文本可能是各种语言,总的来说选择标准分析器是没错的。 它把文本分成单词(由Unicode决定),移除大部分标点符号, 最终,将所有单词小写化,这样,结果如下: set, the, shape, to, semi, transparent, by, calling, set_trans, 5 PS:先清洗,再分词,再归一化。 简单analyzer 这个分析器将文本分词的规则是每个字符是不是一个letter, 然后将所有单词小写化,结果如下: set, the, shape, to, semi, transparent, by, calling, set, trans 空格analyzer 依靠空格来分词,不将单词小写化, 结果如下: Set, the, shape, to, semi-transparent, by, calling, set_trans(5) 语言分析器 特定语言分析器是可用的,可以处理特殊字符。 比如,英语分析器附带很多英语过滤单词集合,这些集合包括没啥意义的单词。 那分析器就会去掉这些单词,可以对英语单词进行提取词干, 这是因为英语分析器知道英语的语法规则。 结果如下: set, shape, semi, transpar, call, set_tran, 5 注意:"transparent", "calling", and "set_trans" 已经归一化到词根形式。 什么时候用分析器 当我们索引一个文档,它的整个文档被分析成单词,单词用来创建倒排索引。 尽管如下,当我们搜索全文字段,我们也需要将查询字符串进行同样的分析过程。 实际上也就是说,你之前如何对全文做索引的,这个时候也要对查询字符串做同样的归一化处理。这样才可以保证可以查出来数据。 后面说全文搜索, 当你查询一个全文字段,查询将对查询字符串应用同样的分析器来产生一系列分词后的单词。 当你查询一个具体的字段,查询就不会对查询字符串进行分析,仅仅搜索具体的值。 现在你就理解了之前的: date字段包含了一个具体的值:一个单词 "2014-09-15". _all字段是一个全文字段,所以分析器已经把日期分成3个单词: "2014", "09" and "15". 当我们在_all字段里搜索2014,有12个结果,因为都包含2014这个单词。 GET /_search?q=2014 # 12 results 当我们在_all字段里搜索2014-09-15, 首先会把查询字符串分词为"2014", "09" and "15". 仍然包含了12个tweets,因为都包含2014. GET /_search?q=2014-09-15 # 12 results ! 当我们查询date字段,值为2014-09-15, 搜索会寻找具体的日期,结果只有1个: GET /_search?q=date:2014-09-15 # 1 result 当我们查询date字段,值为2014,就找不到文档。 GET /_search?q=date:2014 # 0 results ! 测试分析器 如果你是一个新手,有时会很难理解分词的具体原理和存储索引的过程。 (不看源码你永远不可能知道,just read the fuc*ing source code please!!!) 为了更好的理解怎样运行的,你可以使用分析API来看文本如何分析的。 在查询字符串参数里指定你想用哪个分析器,body里指定分析的文本。 GET /_analyze?analyzer=standard Text to analyze 结果如下: { "tokens": [ { "token": "text", "start_offset": 0, "end_offset": 4, "type": "<ALPHANUM>", "position": 1 }, { "token": "to", "start_offset": 5, "end_offset": 7, "type": "<ALPHANUM>", "position": 2 }, { "token": "analyze", "start_offset": 8, "end_offset": 15, "type": "<ALPHANUM>", "position": 3 } ] } 这些单词就是真实的被存储在索引里的单词。 position表明单词出现的顺序, start_offset 和 end_offset 表明 字符在原始文本里的位置。 分析API对于理解es的索引很有用。 指定分析器 当es发现有需要索引的String字段,自动认为是全文字符串字段,用标准分析器来分析。 有的时候你可能不想要这个分析器,纳尼? 也许你想采用一个不同的分析器,因为你觉得它更合适。 也许你还希望一个string字段就是一个字段,不需要认为是全文字段,比如说字符串类型的userid和内部身份。 这个请看下一回合。