Понедельник go Отличительный индекс для обозначения точки - PullRequest
0 голосов
/ 11 января 2020
  1. У меня есть mongodb v4.2.2, размещенный на Atlas. Имеют коллекцию objects и два поля в ней: metadata как массив объектов, каждый объект имеет одно поле key И второе поле с именем model. Добавлен составной индекс model->metadata.key как обычный. При запуске команды db db.objects.explain('executionStats').distinct('metadata.key', {model: ObjectId('5e18aff58a5aaffdc3d6f26d')}) из консоли он не использует мой индекс model->metadata.key и не использует DISTINCT_SCAN.

  2. Но если я перенесу данные в другую коллекцию, скажем, что objectKeys имеет два поля, такие как key, model, и снова добавит обычный составной индекс model->key и команду run db.objectKeys.explain('executionStats').distinct('key', {model: ObjectId('5e18aff58a5aaffdc3d6f26d')}) успешно применяет DISTINCT_SCAN и использует индекс.

  3. Вопрос. Как заставить MongoDB использовать индексы для поля с точечной нотацией во время отдельной операции?

ДЕТАЛИ ОБНОВЛЕНИЯ:

1.

db.objects.getIndexes();
{
  "v" : 2,
  "key" : {
    "model" : 1,
    "metadata.key" : 1,
    "metadata.value" : 1
  },
  "name" : "model_1_metadata.key_1_metadata.value_1",
  "ns" : "my_db.objects",
  "background" : true
}

db.objects.explain('executionStats').distinct('metadata.key', {model: ObjectId('5e18aff58a5aaffdc3d6f26d')})

"executionStages" : {
  "stage" : "FETCH",
    "nReturned" : 0,
    "executionTimeMillisEstimate" : 0,
    "works" : 1,
    "advanced" : 0,
    "needTime" : 0,
    "needYield" : 0,
    "saveState" : 0,
    "restoreState" : 0,
    "isEOF" : 1,
    "docsExamined" : 0,
    "alreadyHasObj" : 0,
    "inputStage" : {
    "stage" : "IXSCAN",
      "nReturned" : 0,
      "executionTimeMillisEstimate" : 0,
      "works" : 1,
      "advanced" : 0,
      "needTime" : 0,
      "needYield" : 0,
      "saveState" : 0,
      "restoreState" : 0,
      "isEOF" : 1,
      "keyPattern" : {
      "model" : 1,
        "metadata.key" : 1,
        "metadata.value" : 1
    },
    "indexName" : "model_1_metadata.key_1_metadata.value_1",
      "isMultiKey" : true,
      "multiKeyPaths" : {
      "model" : [ ],
        "metadata.key" : [
        "metadata"
      ],
        "metadata.value" : [
        "metadata"
      ]
    },
    "isUnique" : false,
      "isSparse" : false,
      "isPartial" : false,
      "indexVersion" : 2,
      "direction" : "forward",
      "indexBounds" : {
      "model" : [
        "[ObjectId('5e18aff58a5aaffdc3d6f26d'), ObjectId('5e18aff58a5aaffdc3d6f26d')]"
      ],
        "metadata.key" : [
        "[MinKey, MaxKey]"
      ],
        "metadata.value" : [
        "[MinKey, MaxKey]"
      ]
    },
    "keysExamined" : 0,
      "seeks" : 1,
      "dupsTested" : 0,
      "dupsDropped" : 0
  }
}

2.

db.object_keys.getIndexes();

{
  "v" : 2,
  "key" : {
    "models" : 1,
    "key" : 1
  },
  "name" : "models_1_key_1",
  "ns" : "my_db.object_keys",
  "background" : true
},

db.object_keys.explain('executionStats').distinct('key', {models: ObjectId('5e18aff58a5aaffdc3d6f26d')})

"executionStages" : {
  "stage" : "PROJECTION_COVERED",
    "nReturned" : 0,
    "executionTimeMillisEstimate" : 0,
    "works" : 1,
    "advanced" : 0,
    "needTime" : 0,
    "needYield" : 0,
    "saveState" : 0,
    "restoreState" : 0,
    "isEOF" : 1,
    "transformBy" : {
    "_id" : 0,
      "key" : 1
  },
  "inputStage" : {
    "stage" : "DISTINCT_SCAN",
      "nReturned" : 0,
      "executionTimeMillisEstimate" : 0,
      "works" : 1,
      "advanced" : 0,
      "needTime" : 0,
      "needYield" : 0,
      "saveState" : 0,
      "restoreState" : 0,
      "isEOF" : 1,
      "keyPattern" : {
      "models" : 1,
        "key" : 1
    },
    "indexName" : "models_1_key_1",
      "isMultiKey" : true,
      "multiKeyPaths" : {
      "models" : [
        "models"
      ],
        "key" : [ ]
    },
    "isUnique" : false,
      "isSparse" : false,
      "isPartial" : false,
      "indexVersion" : 2,
      "direction" : "forward",
      "indexBounds" : {
      "models" : [
        "[ObjectId('5e18aff58a5aaffdc3d6f26d'), ObjectId('5e18aff58a5aaffdc3d6f26d')]"
      ],
        "key" : [
        "[MinKey, MaxKey]"
      ]
    },
    "keysExamined" : 0
  }
}

Итак, как вы можете видеть в первом случае, он использует сканирование индекса IXSCAN, а во втором - DISTINCT_SCAN, который считается более быстрым. Разница в том, что в первом случае поле metadata является массивом объектов, а во втором случае поле key является строкой

...