1

I have the following data in a collection named articles :

{
  "_id": "1",
  "attributes": [
    {
      "id": "providercode",
      "value": "code1"
    },
    {
      "id": "otherAttribute",
      "value": "very long value than will be longer than 1024 bytes limit of an index value so I will get 'got unwanted exception: WiredTigerIndex::insert: key too large to index'"
    },
    {
      "id": "objectAttr",
      "value": {
        "ican": "alsobeanobject"
      }
    }
  ]
}

I want to get the articles having "code1" in its providercode attribute.

I am searching with this query :

db.articles.find({ attributes: { $elemMatch: { "id": "providercode", "value": "code1" }}})

I need an index that will apply to the previous query.

I tried this index :

db.articles.ensureIndex({ "attributes.id": 1, "attributes.value": 1 })

It could work but it won't because of the potential very big strings in attributes.value.

I get the error :

Error got unwanted exception: WiredTigerIndex::insert: key too large to index

My question(s) is (are) :

  • is there a way to make a sort of partial index on my providercode attribute (indexing only the providercode part of the attributes) ?
  • Is there a way to skip the indexing of an invalid (too long) attribute.value (like with mongodb < 2.6) ?

Additional infos :

  • providercode value will always be a string short enough for an index
  • each article document will have a providercode attribute
  • I am with a mongodb 4.X
Julien TASSIN
  • 5,004
  • 1
  • 25
  • 40

1 Answers1

0

The solution was in fact simple.

I made these indexes :

db.articles.ensureIndex({ "attributes.id": 1 });
db.articles.ensureIndex({ "attributes.value": "hashed" });

And my query is now using the index on attributes.value

Julien TASSIN
  • 5,004
  • 1
  • 25
  • 40