gpt4 book ai didi

django - 在Django Haystick/Elasticsearch中找不到不是单词的字符串

转载 作者:行者123 更新时间:2023-12-03 01:53:39 27 4
gpt4 key购买 nike

我正在将带有Elasticsearch的Django Haystack用作实时航类 map 服务的后端。

我已经正确设置了所有搜索索引,但是对于非全字词的搜索,我很难返回结果(例如航空呼号,其中一些采用N346IF的样式,其他包含全字词,例如Speedbird 500) 。查询的N346IF样式不会产生任何结果,而对于后一个示例,我可以轻松地返回结果。

我进行如下查询:

queryResults = SearchQuerySet().filter(content=q) # where q is the query in string format

(请注意,过去我使用了 AutoQuery查询集,但是文档列出它仅跟踪单词,因此我现在传递一个原始字符串)。

我将搜索索引字段设置为带有搜索模板的 EdgeNgramField

我有一个具有以下索引设置的自定义后端(以及 snowball分析器和 pattern分析器):
ELASTICSEARCH_INDEX_SETTINGS = {
'settings': {
"analysis": {
"analyzer": {
"ngram_analyzer": {
"type": "custom",
"tokenizer": "lowercase",
"filter": ["haystack_ngram"]
},
"edgengram_analyzer": {
"type": "custom",
"tokenizer": "lowercase",
"filter": ["haystack_edgengram"]
}
},
"tokenizer": {
"haystack_ngram_tokenizer": {
"type": "nGram",
"min_gram": 4,
"max_gram": 15,
},
"haystack_edgengram_tokenizer": {
"type": "edgeNGram",
"min_gram": 4,
"max_gram": 15,
"side": "front"
}
},
"filter": {
"haystack_ngram": {
"type": "nGram",
"min_gram": 4,
"max_gram": 15
},
"haystack_edgengram": {
"type": "edgeNGram",
"min_gram": 4,
"max_gram": 15
}
}
}
}
}

ELASTICSEARCH_DEFAULT_ANALYZER = "pattern"

我的后端配置为:
class ConfigurableElasticBackend(ElasticsearchSearchBackend):

def __init__(self, connection_alias, **connection_options):
super(ConfigurableElasticBackend, self).__init__(
connection_alias, **connection_options)
user_settings = getattr(settings, 'ELASTICSEARCH_INDEX_SETTINGS')
if user_settings:
setattr(self, 'DEFAULT_SETTINGS', user_settings)

class ConfigurableElasticBackend(ElasticsearchSearchBackend):

DEFAULT_ANALYZER = "pattern"

def __init__(self, connection_alias, **connection_options):
super(ConfigurableElasticBackend, self).__init__(
connection_alias, **connection_options)

user_settings = getattr(settings, 'ELASTICSEARCH_INDEX_SETTINGS')
user_analyzer = getattr(settings, 'ELASTICSEARCH_DEFAULT_ANALYZER')

if user_settings:
setattr(self, 'DEFAULT_SETTINGS', user_settings)
if user_analyzer:
setattr(self, 'DEFAULT_ANALYZER', user_analyzer)

def build_schema(self, fields):
content_field_name, mapping = super(ConfigurableElasticBackend,
self).build_schema(fields)

for field_name, field_class in fields.items():
field_mapping = mapping[field_class.index_fieldname]

if field_mapping['type'] == 'string' and field_class.indexed:
if not hasattr(field_class, 'facet_for') and not \
field_class.field_type in('ngram', 'edge_ngram'):
field_mapping['analyzer'] = self.DEFAULT_ANALYZER
mapping.update({field_class.index_fieldname: field_mapping})
return (content_field_name, mapping)

class ConfigurableElasticSearchEngine(ElasticsearchSearchEngine):
backend = ConfigurableElasticBackend

为了成功产生均为和/或 N346IF样式的字符串的搜索模式的结果,正确的设置是什么?

感谢任何输入,如果这类似于另一个问题(找不到任何相关内容),则表示歉意。

编辑:由solarissmoke请求,此模型的模式:
class FlightIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.EdgeNgramField(document=True, use_template=True)
flight = indexes.CharField(model_attr='flightID')
callsign = indexes.CharField(model_attr='callsign')
displayName = indexes.CharField(model_attr='displayName')
session = indexes.CharField(model_attr='session')

def prepare_session(self, obj):
return obj.session.serverId

def get_model(self):
return Flight

文本索引为:
flight___{{ object.callsign }}___{{ object.displayName }}

最佳答案

它没有完全解释您所看到的行为,但是我认为问题在于您如何为数据建立索引-特别是text字段(当您对content进行过滤时会搜索到的内容)。

以您提供的示例数据为例,即呼号N133TC,航类名称Shahrul Nizam。该数据的text文档变为:

flight___N133TC___Shahrul Nizam

您已将此字段设置为 EdgeNgramField(最少4个字符,最多15个字符)。这是对本文档建立索引时生成的ngram(为简单起见,我忽略了小写过滤器):
flig
fligh
flight
flight_
flight___
flight___N
flight___N1
flight___N13
flight___N133
flight___N133T
flight___N133TC
Niza
Nizam

请注意, token 生成器不会在下划线上分割。现在,如果您搜索 N133TC,则上述所有标记都将不匹配。 (我无法解释 Shahrul为什么起作用...不应该这样,除非我错过了什么,或者该字段的开头有空格)。

如果您将 text文档更改为:
flight N133TC Shahrul Nizam

然后索引的 token 将是:
flig
flight
N133
N133T
N133TC
Shah
Shahr
Shahru
Shahrul
Niza
Nizam

现在,对 N133TC的搜索应该匹配。

还要注意,文档中的 flight___字符串会生成一堆(很可能是)无用标记的负载-除非这是故意的,否则您可能会更好。

关于django - 在Django Haystick/Elasticsearch中找不到不是单词的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38285856/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com