Django_elasticsearch_dsl_drf未返回预期结果

问题描述 投票:0回答:1

我正在我的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", "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",
        )

viewset

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时,它给了我一个结果。

我的代码怎么了?任何帮助将不胜感激:-)

python django elasticsearch
1个回答
0
投票

如果要在某些单词中搜索部分字符串,则应使用edge-ngram token filter-doc here表示。使用此方法,您还可以在搜索栏上执行自动补全功能,因为可以搜索单词开头的部分字符串。您应该实现一个特定的search_analyzer,因为您希望不要使用edge-ngram令牌过滤器对输入的查询字符串进行令牌化-为便于说明,请查看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"
          }
        }
      }
    } 
© www.soinside.com 2019 - 2024. All rights reserved.