Search code examples
mongodbindexingschema-design

Can I utilize indexes when querying by MongoDB subdocument without known field names?


I have a document structure like follows:

{
    "_id": ...,
    "name": "Document name",
    "properties": {
        "prop1": "something",
        "2ndprop": "other_prop",
        "other3": ["tag1", "tag2"],
    }
}

I can't know the actual field names in properties subdocument (they are given by the application user), so I can't create indexes like properties.prop1. Neither can I know the structure of the field values, they can be single value, embedded document or array.

Is there any practical way to do performant queries to the collection with this kind of schema design?

One option that came to my mind is to add a new field to the document, index it and set used field names per document into this field.

{
    "_id": ...,
    "name": "Document name",
    "properties": {
        "prop1": "something",
        "2ndprop": "other_prop",
        "other3": ["tag1", "tag2"],
    },
    "property_fields": ["prop1", "2ndprop", "other3"]
}

Now I could first run query against property_fields field and after that let MongoDB scan through the found documents to see whether properties.prop1 contains the required value. This is definitely slower, but could be viable.


Solution

  • One way of dealing with this is to use schema like below.

    {
        "name" : "Document name",
        "properties" : [
            {
                "k" : "prop1",
                "v" : "something"
            },
            {
                "k" : "2ndprop",
                "v" : "other_prop"
            },
            {
                "k" : "other3",
                "v" : "tag1"
            },
            {
                "k" : "other3",
                "v" : "tag2"
            }
        ]
    }
    

    Then you can index "properties.k" and "properties.v" for example like this:

    db.foo.ensureIndex({"properties.k": 1, "properties.v": 1})