skip to Main Content

Does MongoDB createIndexes() method, support specifying individual options for each index set in the script. Something like this below, which is not working by the way.

Ref – https://www.mongodb.com/docs/v5.0/reference/method/db.collection.createIndexes/#mongodb-method-db.collection.createIndexes

var indexes = [
  {
    key: { "productId":1, "productName":1 },
    partialFilterExpression: { "catalog": { $exists: true} },
    name:"productId_productName_catalog_partial"
  },
  {
    key: { "productId":1, "createdDate":1 },
    sparse: true,
    name:"productId_createdDate_only"
  }
  
];
db.product.createIndexes(indexes);

Error

{
    "message" : "Error in specification { key: { key: { productId: 1, productName: 1 }, partialFilterExpression: { catalog: { $exists: true } }, name: 'productId_productName_catalog_partial' }, name: 'key_[object Object]_partialFilterExpression_[object Object]_name_productId_productName_catalog_partial' } :: caused by :: Unknown index plugin 'productId_productName_catalog_partial'",
    "ok" : 0,
    "code" : 67,
    "codeName" : "CannotCreateIndex"
}

2

Answers


  1. Chosen as BEST ANSWER

    Looks like the below way of execution works fine with multiple index set with different option specification.

    "name" field is a mandatory one which also makes it to work.

    db.runCommand({
        createIndexes: "product",
        indexes: [
            {
                key: { "productId": 1, "productName": 1 },
                partialFilterExpression: { "catalog": { $exists: true } },
                name: "productId_productName_catalog_partial"
            },
            {
                key: { "productId": 1, "createdDate": 1 },
                sparse: true,
                name: "productId_createdDate_only"
            }
        ]
    
    });
    

    Output

    {
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 3,
        "createdCollectionAutomatically" : false,
        "ok" : 1
    }
    

  2. Update

    While what you describe does seem to be a limitation of the helper/wrapper function, it does not seem to be a limitation of the underlying createIndexes command itself.

    Here is an example that creates three indexes each with different options/properties:

    > db.foo.getIndexes()
    [ 
      { v: 2, key: { _id: 1 }, name: '_id_' } 
    ]
    rS [direct: primary] test> db.foo.runCommand({
      createIndexes: 'foo',
      indexes: [
        { key: { x: 1 }, name: 'x_1', unique: true },
        { key: { y: 1 }, name: 'y_1', sparse: true },
        {
          key: { z: 1 },
          name: 'z_1',
          partialFilterExpression: { z: { exists: true } }
        }
      ]
    });
    {
      numIndexesBefore: 1,
      numIndexesAfter: 4,
      ok: 1,
      ...
    }
    rS [direct: primary] test> db.foo.getIndexes()
    [
      { v: 2, key: { _id: 1 }, name: '_id_' },
      { v: 2, key: { x: 1 }, name: 'x_1', unique: true },
      { v: 2, key: { y: 1 }, name: 'y_1', sparse: true },
      {
        v: 2,
        key: { z: 1 },
        name: 'z_1',
        partialFilterExpression: { z: { exists: true } }
      }
    ]
    

    Original answer regarding the helper/wrapper function below.


    The Options section of the documentation you linked has this to say on the matter:

    IMPORTANT

    When you specify options to db.collection.createIndexes(), the options apply to all of the specified indexes. For example, if you specify a collation option, all of the created indexes will include that collation.

    db.collection.createIndexes() will return an error if you attempt to create indexes with incompatible options or too many arguments. Refer to the option descriptions for more information.

    That, and the outcome of your testing, suggests that the answer to your question is: No, specifying options for the indexes individually is not supported with this command.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search