带有edgeNgram过滤器的自定义分析器不起作用

时间:2017-10-26 08:26:28

标签: python django elasticsearch django-haystack

我需要在我的网站上进行部分搜索。最初我直接使用edgeNgramFeild它没有按预期工作。所以我使用自定义分析器的自定义搜索引擎。我正在使用Django-haystack。

'settings': {
       "analysis": {
           "analyzer": {
               "ngram_analyzer": {
                   "type": "custom",
                   "tokenizer": "lowercase",
                   "filter": ["haystack_ngram"]
               },
               "edgengram_analyzer": {
                   "type": "custom",
                   "tokenizer": "lowercase",
                   "filter": ["haystack_edgengram"]
               },
               "suggest_analyzer": {
                   "type":"custom",
                   "tokenizer":"standard",
                   "filter":[
                       "standard",
                       "lowercase",
                       "asciifolding"
                   ]
               },
           },
           "tokenizer": {
               "haystack_ngram_tokenizer": {
                   "type": "nGram",
                   "min_gram": 3,
                   "max_gram": 15,
               },
               "haystack_edgengram_tokenizer": {
                   "type": "edgeNGram",
                   "min_gram": 2,
                   "max_gram": 15,
                   "side": "front"
               }
           },
           "filter": {
               "haystack_ngram": {
                   "type": "nGram",
                   "min_gram": 3,
                   "max_gram": 15
               },
               "haystack_edgengram": {
                   "type": "edgeNGram",
                   "min_gram": 2,
                   "max_gram": 15
               }
           }
       }
   } 

使用edgengram_analyzer进行索引,使用suggest_analyzer进行搜索。这在某种程度上起作用。但是,它并不适用于数字,例如,当输入30时,它不会搜索303,也会搜索包含字母和数字的单词。所以我搜索了各种网站。

他们建议使用标准或whitespace标记器和haystack_edgengram过滤器。但它并没有起作用,抛开数字部分搜索甚至不能用于字母表。建议后的设置:

'settings': {
        "analysis": {
            "analyzer": {
                "ngram_analyzer": {
                    "type": "custom",
                    "tokenizer": "lowercase",
                    "filter": ["haystack_ngram"]
                },
                "edgengram_analyzer": {
                    "type": "custom",
                    "tokenizer": "whitepsace",
                    "filter": ["haystack_edgengram"]
                },
                "suggest_analyzer": {
                    "type":"custom",
                    "tokenizer":"standard",
                    "filter":[
                        "standard",
                        "lowercase",
                        "asciifolding"
                    ]
                },
            },
            "filter": {
                "haystack_ngram": {
                    "type": "nGram",
                    "min_gram": 3,
                    "max_gram": 15
                },
                "haystack_edgengram": {
                    "type": "edgeNGram",
                    "min_gram": 2,
                    "max_gram": 15
                }
            }
        }
    } 

lowercase tokenizer以外的任何其他内容都可以与django-haystack一起使用吗?或haystack_edgengram过滤器不适合我。根据我的知识,它应该像这样工作。考虑2 Lazy Dog提供的文本。它应该使用whitespace [2,Lazy,Dog]获得这样的令牌。然后应用haystack_edgengram过滤器,它应该生成令牌[2,la,laz,lazy,do,dog]。这样做不起作用。我做错了什么?

我的要求是例如文本2 Lazy Dog,当某些类型2 Laz应该有用时。

编辑:

在我的假设中,小写标记器正常工作。但是,如果是上述文本,则会省略2并创建令牌[lazy,dog]。为什么标准或空格标记器无法工作?

2 个答案:

答案 0 :(得分:2)

在ngrams过滤器中,您可以定义min_gram,它是创建的令牌的最小长度。在你的情况下' 2'长度为1,因此在ngram过滤器中忽略它。

解决这个问题的最简单方法是将min_gram更改为1.更复杂的方法是将一些标准分析器与整个关键字相匹配(对于较短的术语很有用)和ngram analzyer用于部分匹配(对于较长的术语) - 也许有一些bool查询。

您还可以将ngrams更改为从' 1'在向Elasticsearch发送查询之前,搜索框中的字符至少需要3个字母。

答案 1 :(得分:-1)

我自己和@ jgr的建议找到了答案:

ELASTICSEARCH_INDEX_SETTINGS = {
    "settings": {
        "analysis": {
            "analyzer": {
                "ngram_analyzer": {
                    "type": "custom",
                    "tokenizer": "standard",
                    "filter": ["haystack_ngram"]
                },
                "edgengram_analyzer": {
                    "type": "custom",
                    "tokenizer": "standard",
                    "filter": ["haystack_edgengram","lowercase"]
                },
                "suggest_analyzer": {
                    "type":"custom",
                    "tokenizer":"standard",
                    "filter":[
                        "lowercase"
                    ]

                }
            },
            "filter": {
                "haystack_ngram": {
                    "type": "nGram",
                    "min_gram": 1,
                    "max_gram": 15
                },
                "haystack_edgengram": {
                    "type": "edgeNGram",
                    "min_gram": 1,
                    "max_gram": 15
                }
            }
        }
    }
}

ELASTICSEARCH_DEFAULT_ANALYZER = "suggest_analyzer"