0

In MongoDB, I have the following document

{
  "_id": { "$oid" : "4FFD813FE4B0931BDAAB4F01" },
  "concepts": {
    "blabla": 20,
    "blibli": 100,
    "blublu": 250,
    ... (many more here)
  }
}

And I would like to index it to be able to query for the "key" of the "concept" array (I know it's not really a mongoDB array...):

db.things.find({concepts:blabla});

Is it possible with the above schema? Or shall I refactor my documents to something like

{
  "_id": { "$oid" : "4FFD813FE4B0931BDAAB4F01" },
  "concepts": ["blabla","blibli","blublu", ... (many more here)]
  }
}

3 Answers 3

2

I'll answer your actual question. No you cannot index on the field names given your current schema. $exists uses an index but that is an existence check only.

There are a lot of problems with a schema like the one you're using and I would suggest a refactor to :

{
  "_id": { "$oid" : "4FFD813FE4B0931BDAAB4F01" },
  "concepts": [
    {name:"blabla", value: 20},
    {name:"blibli", value: 100},
    {name:"blublu", value: 250},
    ... (many more here)
  ]
}

then index {'concepts.name:1'} and you can actually query on the concept names rather than just check for the existence.

TL;DR : No you can't.

Sign up to request clarification or add additional context in comments.

Comments

1

You can query field presence with specific query:

db.your_collection.find({"concept.yourfield": { $exists: true }})

(notice the $exists)

It will return all your document where yourfield is a field of concept subdocument

edit: this solution is only about query. Indexes contains values not field.

4 Comments

Thanks Aurelien. How do I make MongoDB index only the keys (not the values)?
You can't. Keys are never part of index data and you should never have a schema where keys are data.
Oups I didnt read enough about the index. So yes, you can still use my method to find only specific document but you cannot index, as Remon said. Except if you create an index on each field of concept, which is probably not a nice idea.
Thanks guys. Remon, you are right -- we should not use a schema where keys are data.
0

MongoDB indexes each value of the array so you can query for individual items.As you can find here.

But in nested arrays you need to tell to index mongodb to index your sub-fields.

  db.col1.ensureIndex({'concepts.blabla':1})
  db.col1.ensureIndex({'concepts.blublu':1})
    db.col1.find({'concepts.blabla': 20}).explain()
    {
        "cursor" : "BtreeCursor concepts.blabla_1",
        "nscanned" : 1,
        "nscannedObjects" : 1,
        "n" : 1,
        "millis" : 0,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : false,
        "indexOnly" : false,
        "indexBounds" : {
            "concepts.blabla" : [
                [
                    20,
                    20
                ]
            ]
        }
    }

After creating the index , the cursor type changes itself from BasicCursor to BtreeCursor.

if you create your document as you stated at the end of your question

{
  "_id": { "$oid" : "4FFD813FE4B0931BDAAB4F01" },
  "concepts": ["blabla","blibli","blublu", ... (many more here)]
  }
}

just the indexing will be enough as below:

db.col1.ensureIndex({'concepts':1})

2 Comments

Maybe I was not clear, but I am only interested in the presence of keys (here: blabla, blibli), not in the values (here: 20, 100).
the indexed keys can presence only if the the key has a value ( even null).Else there is no meaning of indexes if you will not use it in query for upsert or find.You will just increase memory consumption.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.