Python Django_elasticsearch_dsl_drf未返回预期结果
我在django应用程序中应用了弹性搜索,下面是我的代码片段 documents.pyPython Django_elasticsearch_dsl_drf未返回预期结果,python,django,
elasticsearch,Python,Django,
elasticsearch,我在django应用程序中应用了弹性搜索,下面是我的代码片段 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",
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",
)
视图集
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',
}
下面是我的数据
当我点击http://127.0.0.1:8000/ads/search/?search=Tit
当我点击http://127.0.0.1:8000/ads/search/?search=a
它给了我一个结果
我的代码怎么了?任何帮助都将不胜感激:-)使用
关键字
分析器,整个输入字符串将按原样标记为倒排索引,因此您只能通过精确匹配进行搜索。我在python中使用elasticsearch库,但我对elasticsearch dsl不太了解。我将尝试使用纯弹性配置回答您的问题,然后您应该使用python中的elasticsearch dsl
库搜索如何实现该配置。如果您还想搜索某些单词中的部分字符串,则应使用边缘ngram标记过滤器
-doc标记它们。使用此方法,您还可以在搜索栏上执行自动补全,因为单词开头的部分字符串是可搜索的。您应该实现一个特定的search\u analyzer
,因为您不希望您的输入查询字符串使用edge ngram标记过滤器进行标记化-有关解释,请查看
如果你不喜欢这个解决方案,因为你也会在一个词的中间搜索部分字符串,比如查询<代码> ITL<代码>来检索<代码>标题>代码>字符串,你应该从头开始执行一个新的<代码> ngram tokisher:<代码> -doc:
结果是正确的。。你期望的输出是什么?您是否希望字段标题自动完成,并将停止字从描述字段中删除?我的问题是为什么
search=Tit
没有返回任何内容?因为您已在文本数据类型上设置了关键字分析器,为什么针对标题字段查询Tit应该根据您的要求返回一些内容?您试图实现什么样的配置?标题字段包含Tit
,这正是我所期望的。我应该如何在标题和描述字段上搜索?谢谢您的帮助。我很感激。我会试着做另一台分析仪。让我们看看。如果可以帮助elasticsearch dsl库的HonzaKral th维护者建议使用suggester方法:
{
"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"
}
}
}
}
{
"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"
}
}
}
}