[Python] Elasticsearch search only by one field

Discussão em 'Python' iniciado por Stack, Junho 26, 2025.

  1. Stack

    Stack Membro Participativo

    I have app on drf and i added elasticsearch(django_elasticsearch_dsl) for searching. But i faced with problem, when i want to search on two or more fields, elastic searching only by one field.

    I'm trying to search by both 'title' and 'description', but it only searches in the 'title' field.

    Django model

    class Product(TimestampMixin, HistoricalModel, models.Model):
    class Status(models.TextChoices):
    NEW = 'new', _('New')
    USED = 'used', _('Used')

    class PublicationStatus(models.TextChoices):
    ACTIVE = 'active', _('Active')
    INACTIVE = 'inactive', _('Inactive')
    DRAFT = 'draft', _('Draft') # Очікуючі
    REJECTED = 'rejected', _('Rejected') # Відхилені
    SOLD = 'sold', _('Sold')
    DELETED = 'deleted', _('Deleted')

    title = models.CharField(_('Product name'), max_length=255)
    description = models.TextField(
    verbose_name=_('Product description'),
    validators=[
    MinLengthValidator(settings.MIN_LENGTH_DESCRIPTION, message=_('Product description is too short')),
    MaxLengthValidator(settings.MAX_LENGTH_DESCRIPTION, message=_('Product description is too long')),
    ],
    )
    ...


    Document

    @registry.register_document
    class ProductDocument(Document):
    title = fields.TextField(analyzer="multilang_analyzer")
    description = fields.TextField(analyzer="multilang_analyzer")

    class Index:
    name = "products"
    settings = {
    'number_of_shards': 1,
    'number_of_replicas': 1,
    'analysis': {
    'analyzer': {
    'multilang_analyzer': {
    'type': 'custom',
    'tokenizer': 'standard',
    'char_filter': ['html_strip'],
    'filter': [
    'lowercase',
    'russian_stop',
    'ukrainian_stop',
    'english_stop',
    'russian_stemmer',
    'english_stemmer'
    ]
    }
    },
    'filter': {
    'russian_stop': {'type': 'stop', 'stopwords': '_russian_'},
    'ukrainian_stop': {'type': 'stop', 'stopwords': '_ukrainian_'},
    'english_stop': {'type': 'stop', 'stopwords': '_english_'},
    'russian_stemmer': {'type': 'stemmer', 'language': 'russian'},
    'english_stemmer': {'type': 'stemmer', 'language': 'english'}
    }
    }
    }

    class Django:
    model = Product
    fields = ['title', 'description']


    view

    class SearchProductView(ListAPIView):
    serializer_class=ProductSerializer

    def get_queryset(self):
    q = self.request.GET.get("query", "")
    if q:
    search = (ProductDocument.search()
    .query('multi-match', query=q, fields=["title^2", "description"]))
    response = search.execute()
    return response


    serializer

    class ProductSerializer(serializers.ModelSerializer):
    category = CategorySerializer(read_only=True)
    category_id = serializers.PrimaryKeyRelatedField(queryset=Category.objects.all(), write_only=True, required=True)
    prices = PriceSerializer(many=True, required=False, read_only=True)
    amount = serializers.DecimalField(
    max_digits=13,
    decimal_places=2,
    min_value=MIN_PRICE,
    write_only=True,
    )
    currency = serializers.PrimaryKeyRelatedField(queryset=Currency.objects.all(), write_only=True)
    images = ProductImageSerializer(many=True, source='product_images', read_only=True)
    uploaded_images = serializers.ListField(
    child=serializers.ImageField(use_url=True, allow_null=True),
    write_only=True,
    required=False,
    allow_empty=True,
    )
    video = ProductVideoSerializer(source='product_videos', read_only=True, many=True)
    upload_video = serializers.FileField(write_only=True, required=False)
    seller = serializers.SerializerMethodField(read_only=True)
    status = serializers.ChoiceField(choices=Product.Status.choices)


    For example i have instance with these data

    {"**id**": 4,
    "**title**": "Нові стоїки 52 тижні для наповненого життя",
    "description": "Книга ''Нові стоїки. 52 тижні для наповненого життя''. Прочитана 1 раз, стан нової. Можна забрати у Львові на Зеленій.\r\n\r\nКнижка про філософію стоїцизму — вчення, ... .",
    ...


    curl -X GET "http://elasticsearch:9200/products/_search?pretty"

    "_index" : "products",
    "_id" : "4",
    "_score" : 1.0,
    "_source" : {
    "title" : "Нові стоїки 52 тижні для наповненого життя",
    "description" : "Книга ''Нові стоїки. 52 тижні для наповненого життя''. Прочитана 1 раз, стан нової. Можна забрати у Львові на Зеленій.\r\n\r\nКнижка про філософію стоїцизму — вчення, яке сьогодні набуває все більше популярності. Античні стоїки уміли те..."


    And i want to find by word 'Книга' (that is first in desc) but elastic searchs only in title where this word is missing and i get

    {
    "count": 0,
    "next": null,
    "previous": null,
    "results": []
    }


    For instance i search by Нові (that is first in title) and

    "count": 1,
    "next": null,
    "previous": null,
    "results": [
    {
    "id": 4,
    "slug": "novi-stoiki-52-tizhni-dlia-napovnenogo-zhittia4",
    "title": "Нові стоїки 52 тижні для наповненого життя",
    "status": "Used",
    ...


    Even if i add description field to serializer nothing changes

    Continue reading...

Compartilhe esta Página