使用 django-elasticsearch-dsl-drf 搜索单词的一部分

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

我正在构建一个 Django 应用程序,其中包含使用 django_elasticsearch_dsl_drf 库使用弹性搜索的搜索引擎。我想让用户只搜索字母或单词的一部分,弹性搜索返回包含这些字母的所有单词。例如,如果用户提交了“合法”一词,结果将是所有包含“合法、合法、非法、非法”的文章。我已经使用 nGram tokenizer 来制作这个但是它不起作用,因为当我提交这个词时没有结果显示给我。

这是 documents.py 中最重要的部分:

from django_elasticsearch_dsl import Document, fields, Index
from django_elasticsearch_dsl.registries import registry
from django.conf import settings
from .models import *
from elasticsearch_dsl import analyzer, tokenizer

autocomplete_analyzer = analyzer('autocomplete_analyzer',
            tokenizer=tokenizer('trigram', 'nGram', min_gram=1, max_gram=20),
            filter=['lowercase']
        )

entry_index=Index('entries')

@registry.register_document
class EntryDocument(Document):
    title = fields.TextField(
        attr='title',
        fields={
            'raw': fields.TextField(required=True,analyzer=autocomplete_analyzer),
            'suggest': fields.CompletionField(),
            
        }
    )
    body = fields.TextField(
        attr='body',
        fields={
            'raw': fields.TextField(required=True,analyzer=autocomplete_analyzer),
            # 'suggest': fields.CompletionField()
        }
    )


    class Index:
        name = 'entries'
        settings = {
            "number_of_shards": 1,
            "number_of_replicas": 0,
            'max_ngram_diff': 20 
        }

    class Django:
        model = entry
        fields= []

更多详情: 模型.py:

class entry(models.Model):
    title = models.CharField(max_length=600)
    body = models.TextField()

Serializers.py:

class EntryDocumentSerializer(DocumentSerializer):
    class Meta:
        document = EntryDocument

        fields = (
            'title',
            'body',
            'entryOrigin'
        )

views.py:

class EntryDocumentView(DocumentViewSet):
    document = EntryDocument
    serializer_class = EntryDocumentSerializer

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

    search_fields = (
        'title',
        'body'
    )

    filter_fields = {
        'title': {
        'field' : 'title',
        'lookups': [
                LOOKUP_FILTER_RANGE,
                LOOKUP_QUERY_IN,
                LOOKUP_QUERY_GT,
                LOOKUP_QUERY_GTE,
                LOOKUP_QUERY_LT,
                LOOKUP_QUERY_LTE,
            ],

        },
        'body': {
        'field': 'body',
         'lookups': [
            LOOKUP_FILTER_RANGE,
            LOOKUP_QUERY_IN,
            LOOKUP_QUERY_GT,
            LOOKUP_QUERY_GTE,
            LOOKUP_QUERY_LT,
            LOOKUP_QUERY_LTE,
            ],

        },

        'entryOrigin': 'entryOrigin.id'
    }

    suggester_fields = {
         'title_suggest': {
            'field': 'title.suggest',
            'suggesters': [
                SUGGESTER_COMPLETION,
            ],
            'options': {
                'size': 20,  # Override default number of suggestions
                'skip_duplicates':True, # Whether duplicate suggestions should be filtered out.
            },
        },
        'body_suggest': {
            'field': 'body.suggest',
            'suggesters': [
                SUGGESTER_COMPLETION,
            ]}
    }

网址.py:

from django.contrib import admin
from django.urls import path,include
from rest_framework import routers
from thesearchable.views import EntryDocumentView
from rest_framework import routers
router = routers.SimpleRouter(trailing_slash=False)
router.register(r'entry-search', EntryDocumentView, basename='entry-search')


urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('thesearchable.urls')),
   
]

urlpatterns += router.urls

那我怎样才能只搜索单词的一部分呢?

python django elasticsearch search django-rest-framework
© www.soinside.com 2019 - 2024. All rights reserved.