0

In MongoDB, I have documents that look like

{
  _id: 1,
  name: "foo",
  tags: ['someTag', 'someOtherTag'],
}

The large majority of my documents have no tags, so their tags field is set as tags: [], but I need to frequently access the ones that do have tags.

I want to use a partial index here because it would create a much smaller index than if I just created an index on { tags: 1 }, but the best way I could come up with was to do

db.myThings.createIndex({ tags: 1 }, 
  { partialFilterExpression: { "tags.0": { $exists: true } } } });

Which works, in that when I do db.myThings.stats(), it shows it created a much smaller index, but in order to use the index I now need to query by

db.myThings.find({ "tags.0": { $exists: true }, tags: "someTag" })

If I don't include the "tags.0": { $exists: true } in my query, mongo will not use the index.

I know I could create a partial index based on the existence of the tags field itself, but I also want to be able to modify the array with $pull updates, which wouldn't automatically remove the array from the document when pulling the last element.

Is there a better way to do this, where I wouldn't need to always remember to include the "tags.0": { $exists: true } in all of my queries where I want to use the partial index?

axanpi
  • 731
  • 9
  • 16
  • I just want to thank you for pointing me in the right direction with this. I was trying to make a partial unique multikey index, but kept getting tripped up by the empty array. In the end I used your trick to enforce the unique index constraint, and then made a non-unique index for doing actual queries against. In my case, the collection in question is tiny, so the duplicated index entries aren't something I care about. – alsuren Aug 16 '18 at 12:49

1 Answers1

0

If document don't have any tags, don't put tags:[] in the document and create your index with

db.myThings.createIndex({ tags: 1 },{ sparse: true })

what creates sparse index. This creates index only for those documents and tags what really exists.

JJussi
  • 1,540
  • 12
  • 12
  • I should have added (and I have now edited the question to add) that I also want to be able to modify the array with `$pull` updates, which wouldn't automatically remove the array from the document when pulling the last element. – axanpi Mar 29 '17 at 14:19
  • documents with `tags:[]` will be also be indexed when using sparse indexes – Ezequiel Moreno Oct 18 '17 at 17:13