Elasticsearch:用于内容丰富的文本分析

每个文本搜索解决方案都与其提供的文本分析功能一样强大。 Lucene是这样的开源信息检索库,提供了许多文本分析的可能性。 在本文中,我们将介绍ElasticSearch提供的一些主要文本分析功能,这些功能可用来丰富您的搜索内容。

内容丰富

以一个典型的电子商务站点为例,向最终客户提供正确的搜索内容对于企业非常重要。 任何搜索解决方案提供的文本分析策略在其中都扮演着非常重要的角色。 作为搜索用户,我希望查询能够自动返回一些典型的搜索行为,

  • 应该寻找与我的查询文字相符的同义词
  • 应匹配单词和复数个单词或听起来相似的单词以输入查询文本
  • 不应允许搜索受保护的单词
  • 应该允许搜索包含数字或特殊字符的单词
  • 不应允许搜索html标签
  • 应该允许根据字母的接近度和匹配字母的数量搜索文本

在这里丰富内容将是在为内容建立索引和搜索时,向您的内容添加上述搜索功能。

Lucene文字分析

Lucene信息检索 (IR),允许全文索引和搜索功能。 为了快速参考,请检查Lucene中的文本分析 。 在Lucene中,文档包含“文本”字段。 分析是将字段文本进一步转换为术语的过程。 这些术语用于匹配搜索查询。 整个分析过程共有三种主要实现,

  • 分析器:分析器负责构建TokenStream,可由索引和搜索过程使用。
  • 标记生成器:一个标记是一个的TokenStream并负责分手传入的文本为标记。 在大多数情况下,分析器将使用令牌生成器作为分析过程的第一步。
  • TokenFilter: TokenFilter也是TokenStream,负责修改由Tokenizer创建的Token。

分析器内部TokenStreams和TokenFilters的常用用法是使用链接模式,该模式可让您从简单的Tokenizer / TokenFilter构建块构建复杂的分析器。 令牌生成器通过将输入的字符划分为令牌来启动分析过程(大多数这些令牌对应于原始文本中的单词)。 然后,TokenFilters接管其余的分析工作,首先包装Tokenizer,然后依次包装嵌套的TokenFilters。

ElasticSearch文本分析

ElasticSearch使用Lucene内置的文本分析功能,可让您丰富搜索内容。 如上所述,文本分析分为过滤器,标记器和分析器。 ElasticSearch为您提供了一些内置的分析器,这些分析器带有预配置的标记生成器和过滤器。 有关现有分析仪的详细列表,请检查分析的完整列表

更新分析设置

ElasticSearch允许您动态更新索引设置和映射。 要从Java api客户端更新索引设置,

Settings settings = settingsBuilder().loadFromSource(jsonBuilder()
                    .startObject()
                        //Add analyzer settings
                        .startObject("analysis")
                            .startObject("filter")
                                .startObject("test_filter_stopwords_en")
                                    .field("type", "stop")
                                    .field("stopwords_path", "stopwords/stop_en")
                                .endObject()
                                .startObject("test_filter_snowball_en")
                                    .field("type", "snowball")
                                    .field("language", "English")
                                .endObject()
                                .startObject("test_filter_worddelimiter_en")
                                    .field("type", "word_delimiter")
                                    .field("protected_words_path", "worddelimiters/protectedwords_en")
                                    .field("type_table_path", "typetable")
                                .endObject()
                                .startObject("test_filter_synonyms_en")
                                    .field("type", "synonym")
                                    .field("synonyms_path", "synonyms/synonyms_en")
                                    .field("ignore_case", true)
                                    .field("expand", true)
                                .endObject()
                                .startObject("test_filter_ngram")
                                    .field("type", "edgeNGram")
                                    .field("min_gram", 2)
                                    .field("max_gram", 30)
                                .endObject()
                           .endObject()
                           .startObject("analyzer")
                                .startObject("test_analyzer")
                                    .field("type", "custom")
                                    .field("tokenizer", "whitespace")
                                    .field("filter", new String[]{"lowercase",
                                                                    "test_filter_worddelimiter_en",
                                                                        "test_filter_stopwords_en",
                                                                        "test_filter_synonyms_en",
                                                                        "test_filter_snowball_en"})
                                    .field("char_filter", "html_strip")
                                .endObject()
                           .endObject()
                        .endObject()
                    .endObject().string()).build();
 
CreateIndexRequestBuilder createIndexRequestBuilder = client.admin().indices().prepareCreate(indexName);
createIndexRequestBuilder.setSettings(settings);

您还可以在配置文件中设置索引和设置。 上例中提到的路径是相对于已安装elasticsearch服务器的config目录的。 上面的示例允许您为索引创建自定义过滤器和分析器,ElasticSearch具有不同过滤器和标记器的现有组合,允许您为数据选择正确的组合。

同义字

同义词是具有相同或相似含义的词。 同义词扩展是在这里我们使用单词的变体,并在建立索引和/或查询时将其分配给搜索引擎。 向索引设置添加同义词过滤器。

.startObject("test_filter_synonyms_en")
    .field("type", "synonym")
	.field("synonyms_path", "synonyms/synonyms_en")
	.field("ignore_case", true)
	.field("expand", true)
.endObject()

检查同义词过滤器以获取完整的语法。 您可以添加Slor或WordNet格式的同义词。 查看Slor同义词格式以获取更多示例,

# If expand==true, "ipod, i-pod, i pod" is equivalent to the explicit mapping:
ipod, i-pod, i pod => ipod, i-pod, i pod
# If expand==false, "ipod, i-pod, i pod" is equivalent to the explicit mapping:
ipod, i-pod, i pod => ipod

单词表中查找符合您要求的单词和同义词列表。

抽干

词干定义为包含词变体的能力。 例如,任何名词词都将包含变体(其重要性与变体的程度成正比)。对于词干,我们使用语法规则的量化方法来添加词干,并根据词干与词根的分离程度对其进行排序字。 将词干过滤器添加到索引的设置。

.startObject("test_filter_snowball_en")
    .field("type", "snowball")
    .field("language", "English")
.endObject()

有关详细信息,请检查Snowball过滤器语法。 阻止程序通常称为阻止算法或阻止程序。 Lucene分析可以基于算法或基于字典。 雪球 ,基于马丁波特的雪球算法提供所产生的功能,并用作在上面的例子中词干。 检查雪球茎杆的列表以获取受支持的不同语言。 同义词和词干有时会根据文本处理的顺序返回奇怪的结果。 确保按照您的要求使用两者。

停用词

停用词是您不希望用户索引或查询的单词列表。 要将停用词过滤器添加到设置中,

.startObject("test_filter_stopwords_en")
    .field("type", "stop")
    .field("stopwords_path", "stopwords/stop_en")
.endObject()

检查停用词filter的完整语法。 检查英语的Snowball 停用词列表以获取您自己的列表。 检查Solr共享的英语停用词列表。

字定界符

单词定界符过滤器使您可以将单词拆分为子单词,以对子单词进行进一步处理。 要将字定界符过滤器添加到设置中,

.startObject("test_filter_worddelimiter_en")
    .field("type", "word_delimiter")
	.field("protected_words_path", "worddelimiters/protectedwords_en")
	.field("type_table_path", "typetable")
.endObject()

常见的单词拆分基于非字母数字性质,大小写转换和单词内定界符等。检查Word Delimiter Filter的完整语法和不同的可用选项。 受保护单词列表使您可以保护业务相关单词免于在过程中被分隔。

N-gram是给定文本序列的n个字母的连续序列。 要将边缘ngram过滤器添加到设置中,

.startObject("test_filter_ngram")
	.field("type", "edgeNGram")
	.field("min_gram", 2)
	.field("max_gram", 30)
.endObject()

根据您的配置,在索引期间,输入文本将分解为上面配置的多个长度的令牌。 它允许您基于匹配的ngram令牌(也基于接近度)返回结果。 检查Edge NGram过滤器的详细语法

HTML Strip字符过滤器

大多数网站都提供应索引HTML内容。 大多数网站都不需要允许对标准html文本进行索引和查询。 ElasticSearch允许您过滤html标记,这些标记不会被索引,也无法查询。

.startObject("analyzer")
    .startObject("test_analyzer")
		.field("type", "custom")
		.field("tokenizer", "whitespace")
		.field("filter", new String[]{"lowercase", "test_filter_worddelimiter_en", "test_filter_stopwords_en", "test_filter_synonyms_en", "test_filter_snowball_en"})
		.field("char_filter", "html_strip")
    .endObject()
.endObject()

有关详细信息,请检查HTML Strip Char Filter的完整语法。 除了上述常见过滤器外,还有更多可用的过滤器,可让您根据最终用户的要求和业务数据以所需的方式丰富搜索内容。


翻译自: https://www.javacodegeeks.com/2013/05/elasticsearch-text-analysis-for-content-enrichment.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值