gpt4 book ai didi

python - Django_elasticsearch_dsl_drf未返回预期结果

转载 作者:行者123 更新时间:2023-12-03 01:18:52 25 4
gpt4 key购买 nike

我在我的Django应用程序中应用了 flex 搜索,以下是我的代码段

documents.py

ads_index = Index("ads_index")
ads_index.settings(
number_of_shards=1,
number_of_replicas=0
)

html_strip = analyzer(
'html_strip',
tokenizer="standard",
filter=["standard", "lowercase", "stop", "snowball"],
char_filter=["html_strip"]
)


@ads_index.doc_type
class AdDocument(Document):
id = fields.IntegerField(attr='id')

title = fields.TextField(
analyzer=html_strip,
fields={
'title': fields.TextField(analyzer='keyword'),
}
)

description = fields.TextField(
analyzer=html_strip,
fields={
'description': fields.TextField(analyzer='keyword'),
}
)

category = fields.ObjectField(
properties={
'title': fields.TextField(),
}
)

class Django:
model = Ad # The model associated with this Document

# The fields of the model you want to be indexed in Elasticsearch
fields = [
'price',
'created_at',
]

related_models = [Category]

def get_queryset(self):
return super().get_queryset().select_related('category')

def get_instances_from_related(self, related_instance):
if isinstance(related_instance, Category):
return related_instance.ad_set.all()

序列化器
class AdDocumentSerializer(DocumentSerializer):
class Meta:
document = AdDocument
fields = (
"id",
"title",
"description",
"price",
"created_at",
)

View 集
class AdViewSet(DocumentViewSet):
document = AdDocument
serializer_class = AdDocumentSerializer
ordering = ('id',)
lookup_field = 'id'

filter_backends = [
DefaultOrderingFilterBackend,
FilteringFilterBackend,
CompoundSearchFilterBackend,
SuggesterFilterBackend,
]

search_fields = (
'title',
'description',
)

filter_fields = {
'id': {
'field': 'id',
'lookups': [
LOOKUP_FILTER_RANGE,
LOOKUP_QUERY_IN,
LOOKUP_QUERY_GT,
LOOKUP_QUERY_GTE,
LOOKUP_QUERY_LT,
LOOKUP_QUERY_LTE,
],
},
'title': 'title.raw',
'description': 'description.raw',
}

ordering_fields = {
'id': 'id',
}

以下是我的数据

Data

当我按下 http://127.0.0.1:8000/ads/search/?search=Tit时,它什么也不返回,但是当我按下 http://127.0.0.1:8000/ads/search/?search=a时,它却给了我一个结果。

我的代码在哪里错了?任何帮助,将不胜感激 :-)

最佳答案

使用keyword分析器,整个输入字符串将按原样指示为反向索引,因此您只能按完全匹配进行搜索。我在python中使用elasticsearch库,但我不太了解elasticsearch-dsl。我将尝试使用纯 flex 配置来回答您,然后您应该搜索如何在python中使用elasticsearch-dsl库实现该conf。如果您还要在某些单词中搜索部分字符串,则应使用edge-ngram token filter-doc here表示它们。使用此方法,您还可以在搜索栏上执行自动补全功能,因为可以搜索单词开头的部分字符串。您应该实现一个特定的search_analyzer,因为您希望不要使用edge-ngram token 过滤器对输入的查询字符串进行 token 化-作为解释,请查看herehere

{
"settings": {
"number_of_shards": 1,
"analysis": {
"filter": {
"autocomplete_filter": {
"type": "edge_ngram",
"min_gram": 1,
"max_gram": 20
}
},
"analyzer": {
"autocomplete": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"autocomplete_filter"
]
}
}
}
},
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer" : "autocomplete",
"search_analyzer" : "standard"
},
"description": {
"type": "text",
"analyzer" : "autocomplete",
"search_analyzer" : "standard"
}
}
}
}

如果您不喜欢这种解决方案,因为您还会在单词的中间搜索部分字符串(例如查询 itl以检索 title字符串),则应从头开始实现新的 ngram-tokenizer-doc here:
{
"settings": {
"analysis": {
"analyzer": {
"autocomplete": {
"tokenizer": "my_tokenizer",
"filter": ["lowercase"]
}
},
"tokenizer": {
"my_tokenizer": {
"type": "ngram",
"min_gram": 1,
"max_gram": 20,
"token_chars": [
"letter",
"digit"
]
}
}
}
},
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer" : "autocomplete",
"search_analyzer" : "standard"
},
"description": {
"type": "text",
"analyzer" : "autocomplete",
"search_analyzer" : "standard"
}
}
}
}

关于python - Django_elasticsearch_dsl_drf未返回预期结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61285328/

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