Extending multi-match for nested Object objects in MongoDB

Given this works, but how to extend this multi_match to nested ObjectID objects in a MongoDB database:

GET address*/_search/
{
  "query": {
    "multi_match" : {
      "query": "york", 
      "fields": [  "outward_code", "inward_code", "locality",  "po_box_number"] 
    }
  },
	"size": 5
}

i.e it can query outward_code, inward_code as these are:

outward_code: "CF37"
inward_code: "7TZ"

But the locality is an embedded Object:

  locality: Object
    _id: ObjectId('343535455454')
    locality_key: "36910"
    post_town: "YORK"
    dependent_locality: "NETHER POPPELTON"
    double_dependent_locality: "YORK BUSINESS PARK"

Are not queried

I see an Elasticsearch query and that you are talking about MongoDB. How are the two related? I think you may need to provide some more context for someone to be able to help you.

If you have indexed data from MongoDB into Elasticsearch, please provide some details about how the data is structured and the mappings that are in place.

@Christian_Dahlqvist in a Django application we store data in MongoDB via djongo and then Elasticsearch query it, does that help your question?

Elasticsearch can not search data residing in MongoDB, so there must be something that indexes data into Elasticsearch from MongoDB or the application for you to be able to query it from Elasticsearch. You need to check how the data is indexed into Elasticsearch and what the mappings are some someone to be able to help.

But it is already working with simpler types:

outward_code: "CF37"
inward_code: "7TZ"

Just not the embedded types

That depends on how the data is indexed in Elasticsearch. Please provide a sample document from Elasticsearch and the mappings of the index.

Sample MongoDB compass data, in particular locality Object

### documents.py

from django.conf import settings
from django_elasticsearch_dsl import Document, Index, fields
from django_elasticsearch_dsl.registries import registry
from django_elasticsearch_dsl_drf.analyzers import edge_ngram_completion
from django_elasticsearch_dsl_drf.compat import KeywordField, StringField
from elasticsearch import Elasticsearch
from elasticsearch_dsl import Search, analyzer
from paf.models import (
    Address,
    AddressImpSet,
    BuildingName,
    Locality,
    Organisation,
    StandardAddress,
    SubBuildingName,
    Thoroughfare,
    ThoroughfareDescriptor,
    WelshAddress,
)

__all__ = ('AddressDocument',)

print("__name__:", __name__)

client = Elasticsearch(['elasticsearch:9200'])

my_search = Search(using=client)

INDEX = Index(settings.ELASTICSEARCH_INDEX_NAMES[__name__])

INDEX.settings(
    number_of_shards=1,
    number_of_replicas=1,
    # blocks={'read_only_allow_delete': None},
    # # read_only_allow_delete=False
)

html_strip = analyzer(
    'html_strip',
    tokenizer='standard',
    filter=["lowercase", "stop", "snowball"],
    char_filter=["html_strip"]
)

@INDEX.doc_type
class AddressDocument(Document):
    """Address Elasticsearch document."""
    # from class BaseModel
    id = fields.IntegerField(attr='id')

    # ********************************************************************
    # *********************** Main data fields for search ****************
    # ********************************************************************

    outward_code = StringField(
        # attr='outward_code_indexing',
        analyzer=html_strip,
        # fields=__title_fields
        fields={
            'raw': StringField(analyzer='keyword'),
            'suggest': fields.Completion()
        }
    )

    inward_code = StringField(  #fields.TextField(
        # attr='inward_code_indexing',
        analyzer=html_strip,
        fields={
            'raw': StringField(analyzer='keyword'),
            'suggest': fields.Completion()
        }
    )

    locality = StringField(
        attr='locality_indexing',
        analyzer=html_strip,
        fields={
            'raw': StringField(analyzer='keyword'), #, multi=True),
            'suggest': fields.Completion(multi=True),
        },
        # multi=True
    )
 

    thoroughfare = StringField(
        # attr='thoroughfare_indexing',
        analyzer=html_strip,
        fields={
            'raw': StringField(analyzer='keyword'),
            'suggest': fields.Completion()
        }
    )


    thoroughfare_descriptor = StringField(
        attr='thoroughfare_descriptor_indexing',  
        analyzer=html_strip,
        fields={
            'raw': StringField(analyzer='keyword', multi=True),
            'suggest': fields.Completion()
        },
        multi=True
    )

   
  
    class Django(object):
        """Inner nested class Django."""
        model = Address  # The model associated with this Document

    class Meta:
        parallel_indexing = True

        # The fields of the model you want to be indexed in ElasticSearch
        fields = [
            'outward_code',
            'inward_code',
            'aid',
            'locality',
 

            'thoroughfare',
            'thoroughfare_descriptor',
            'dependent_thoroughfare',
            'dependent_thoroughfare_descriptor',
            'oid',
            'addressid',
            'org_key',
            'org_type',
            'building_number',
            'building_name',
            'sub_building_name',
            'number_of_households',
            'concatenation_indicator',
            'delivery_point_suffix',
            'small_user_organisation_indicator',
            'po_box_number',
        ]

        # Ignore auto updating of Elasticsearch when a model is saved or deleted
        # ignore_signals = True

        # Don't perform an index refresh after every update (overrides global setting):
        # auto_refresh = False

        # Paginate the Django queryset used to populate the index with the specified size
        # (by default it uses the database driver's default setting)
        # queryset_pagination = 5000


# def search(locality):
#     query = my_search.query("match", locality=locality)
#     response = query.execute()
#     return response

serializer.py

import json
from django_elasticsearch_dsl_drf.serializers import DocumentSerializer
from rest_framework import serializers
from arthur_paf.paf.models import Address
from arthur_paf.search_indexes.documents.address import AddressDocument


class AddressDocumentSerializer(DocumentSerializer):
    """Serializer for Address document"""

    

class Meta:
        """Meta options."""

        # Specify the corresponding document class
        document = AddressDocument

        # List the serializer fields. Note, that the order of the fields
        # is preserved in the ViewSet.
        fields = [
            'outward_code',
            'inward_code',
           
            'locality',
  
            'thoroughfare',
            'thoroughfare_descriptor',
            'dependent_thoroughfare',
            'dependent_thoroughfare_descriptor',
            'po_box_number',
        ]

Why locality in this context showing only keys but no value?

This seems to be an issue with whatever is indexing data into Elasticsearch from MongoDB. There is nothing from Elastic that I am aware of that do this, so my guess is that it is some kind of third party component. You probably need to bring this up with whoever developed/configured this.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.