ElasticSearch:EdgeNgrams和Numbers

时间:2012-11-29 23:05:04

标签: python elasticsearch django-haystack

关于EdgeNgram如何处理数字的任何想法?

我正在使用ElasticSearch后端运行haystack。我创建了一个EdgeNgram类型的索引字段。该字段将包含一个字符串,其中可能包含单词和数字。

当我使用部分单词对此字段进行搜索时,它的工作方式如何。但如果我输入一个部分号码,我就得不到我想要的结果了。

示例:

我通过输入“edgen”来搜索索引字段“EdgeNgram 12323”,然后我会将索引返回给我。如果我通过输入“123”搜索相同的索引,我什么也得不到。

思想?

2 个答案:

答案 0 :(得分:4)

我在这里试图解决Haystack + Elasticsearch中的同样问题。根据uboness和ComoWhat的提示,我写了一个备用的Haystack引擎(我相信)使EdgeNGram字段处理数字字符串,如单词。其他人可能会受益,所以我想我会分享它。

from haystack.backends.elasticsearch_backend import ElasticsearchSearchEngine, ElasticsearchSearchBackend

class CustomElasticsearchBackend(ElasticsearchSearchBackend):
    """
    The default ElasticsearchSearchBackend settings don't tokenize strings of digits the same way as words, so emplids
    get lost: the lowercase tokenizer is the culprit. Switching to the standard tokenizer and doing the case-
    insensitivity in the filter seems to do the job.
    """
    def __init__(self, connection_alias, **connection_options):
        # see http://stackoverflow.com/questions/13636419/elasticsearch-edgengrams-and-numbers
        self.DEFAULT_SETTINGS['settings']['analysis']['analyzer']['edgengram_analyzer']['tokenizer'] = 'standard'
        self.DEFAULT_SETTINGS['settings']['analysis']['analyzer']['edgengram_analyzer']['filter'].append('lowercase')
        super(CustomElasticsearchBackend, self).__init__(connection_alias, **connection_options)

class CustomElasticsearchSearchEngine(ElasticsearchSearchEngine):
    backend = CustomElasticsearchBackend

答案 1 :(得分:3)

如果您正在使用edgeNGram标记生成器,那么它会将“EdgeNGram 12323”视为单个标记,然后对其应用edgeNGram处理。例如,如果min_grams = 1 max_grams = 4,您将获得索引的以下标记:[“E”,“Ed”,“Edg”,“Edge”]。所以我想这不是你真正想要的 - 考虑使用edgeNGram令牌过滤器:

如果您正在使用edgeNGram令牌过滤器,请确保您使用的是实际对文本“EdgeNGram 12323”进行令牌化的令牌生成器,以生成两个令牌:[“EdgeNGram”,“12323”](标准或whitespace tokenizer会做的伎俩)。然后在它旁边应用edgeNGram过滤器。

一般来说,edgeNGram将采用“12323”并生成诸如“1”,“12”,“123”等标记......