1

Is there any way where I can index my collection according to the keys of a subdocument of object type? And the keys are not uniform in all the documents, different documents have different keys, but there are some common keys. The keys of the subdocument are English words taken from the NLTK words corpus. The document structure is as follows:

{
    _id: 24752893,
    dictionary: {
        attain: {
            language: ....,
            count: ....,
        },
        book: {
            language: ....,
            count: ....,
        },
        obtain: {
            language: ....,
            count: ....,
        },
        ....
    }
},
{
    _id: 6786765789,
    dictionary: {
        book: {
            language: ....,
            count: ....,
        },
        carbon: {
            language: ....,
            count: ....,
        },
        garbage: {
            language: ....,
            count: ....,
        },
        ....
    }
},
........
{
    _id: 76675567,
    dictionary: {
        web: {
            language: ....,
            count: ....,
        },
        obtain: {
            language: ....,
            count: ....,
        },
        carbon: {
            language: ....,
            count: ....,
        },
        ....
    }
}

I want to index according to the keys of the object type dictionary field, i.e. the English words in order to speed up searching. I am using MongoDB version 4.4.

Rifat Rakib
  • 134
  • 7

2 Answers2

2
dictionary: [
    {
    attain: {
        language: ....,
        count: ....,
    },
    book: {
        language: ....,
        count: ....,
    },
    obtain: {
        language: ....,
        count: ....,
    }
}
]

--------------or use Attribute Pattern------------

dictionary: [
    
    {
        k:'attain',
        language: ....,
        count: ....,
    },
    {
        k:'book',
        language: ....,
        count: ....,
    },
    {
        k:'obtain',
        language: ....,
        count: ....,
    }

]

use $elemMatch to find the proper subset, your schema design is wrong Modify your schema like this and use multikey index. https://docs.mongodb.com/manual/core/index-multikey/

db.collection.createIndex( { "dictionary.k": 1, "dictionary.language": 1,"dictionary.count":1 } )

Kaushik Das
  • 405
  • 1
  • 5
  • 12
  • Is it necessary that I put all three fields from the subdocument explicitly into the multikey index? For example, { "dictionary.k": 1, "dictionary.language": 0,"dictionary.count":0 } or { "dictionary.k": 1 }, is there any difference between these two ways of writing the command? – Rifat Rakib Mar 14 '21 at 00:49
  • And is there a way to convert the schema I wrote into the schema you suggested? Or do I have to insert all the documents again with a modified schema? – Rifat Rakib Mar 14 '21 at 00:51
  • 1) yes , you can make one index filed, what you want exactly { "dictionary.k": 1 } is valid. it is depending upon thequery. 2) Convert to existing schema, you need to write js and need to update. it is bit complicated but achievable. OR If you can reinsert it with new schema then its is straight forward. This schema design (2nd) is called attribute pattern, specially made for ecommerce product attribute. – Kaushik Das Mar 14 '21 at 04:33
1

So no, there is no "object keys" index option available for Mongo, what is possible is one of these approaches:

  1. Maintain an array on each document that contains the words it has, have that field indexed, then change your queries to query that field first.

  2. Use wildcard indexes, You should read the wildcard restriction docs to make sure it will answer your query needs as they have some unique behaviours that differ from other index types. The index creation syntax for wildcard is as follows:

db.collection.createIndex( { "dictionary.$**" : 1 } )
Tom Slabbaert
  • 21,288
  • 10
  • 30
  • 43