Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

To search for a portion of a word using django-elasticsearch-dsl-drf, you can use the wildcard search feature.

Here is an example of how to use wildcard search:

  1. Define a search backend in the settings.py file:
ELASTICSEARCH_DSL={
    'default': {
        'hosts': 'localhost:9200'
    },
}
  1. Create a search index that includes the fields you want to search on. For example, in the app's search_indexes.py file:
from elasticsearch_dsl import analyzer
from django_elasticsearch_dsl import DocType, Index, fields

from .models import MyModel

my_index = Index('my_index')

# Define custom analyzer for partial word search
partial_word_analyzer = analyzer(
    'partial_word_analyzer',
    tokenizer='standard',
    filter=['lowercase', 'edge_ngram']
)

@my_index.doc_type
class MyModelIndex(DocType):
    title = fields.TextField(
        analyzer=partial_word_analyzer,
        fields={
            'raw': fields.keyword()
        }
    )
    description = fields.TextField(
        analyzer='english',
        fields={
            'raw': fields.keyword()
        }
    )

    class Meta:
        model = MyModel
        fields = [
            'title',
            'description'
        ]

In this example, we define a custom analyzer that uses the edge_ngram filter to generate partial word searches. We apply this analyzer to the title field. We also define a raw field for each field, which will not be analyzed and allows exact matches.

  1. Create a search view in views.py:
from django.shortcuts import render
from django_elasticsearch_dsl_drf.views import (
    BaseSearchView
)

from .documents import MyModelIndex

class MyModelSearchView(BaseSearchView):
    document = MyModelIndex
    fields = [
        'title',
        'description'
    ]
    serializer_class = MyModelDocumentSerializer
  1. Use the wildcard character (*) in your query parameter to search for partial words. For example, to search for all titles containing the word "elasti":
http://localhost:8000/api/search/?q=title:elasti*

This will return all titles containing words that start with the letters "elasti", such as "Elasticsearch", "Elasticity", etc.

Note that using wildcards can be slow and inefficient, so it is recommended to use an edge_ngram filter for partial word searches as shown in the example.