2016-10-05 2 views
3

Использование mongo 3.2.Использует ли агрегирование mongodb разреженные индексы

Пытался найти информацию, агрегирует mongodb нас редкие индексы.

  1. https://docs.mongodb.com/manual/core/aggregation-pipeline-optimization/

    При размещении в начале трубопровода, $ операция матч использовать подходящие индексы для сканирования только совпадающие документов в коллекции.

  2. https://docs.mongodb.com/manual/core/index-sparse/

    Даже при том, что сортировка по индексированному полю, MongoDB не будет выбрать разреженный индекс для выполнения запроса, чтобы вернуть полные результаты: ... Чтобы использовать разреженный индекс, явно указать индекс с подсказкой()

Итак, вопрос, если у меня есть разреженный индекс, будет Монго агрегации трубопровода с матчем на поле индексируемого нам это, или нет?

+1

Привет, Рамки агрегации имеет возможность добавить 'explain' вариант - если у вас уже есть данные выборки и индекс просто добавить' explain' вариант например: 'db.orders.aggregate ( [ {$ match: {status:" A "}}, {$ group: {_id:" $ cust_id ", всего: {$ sum:" $ amount "} }}, {$ сортировать: {всего: -1}} ], { объяснить: истинно } ) ' это даст вам знать, если он использует его. – cohenjo

+0

@cohenjo объяснить в агрегации не обеспечивает executeStats, поэтому не может проверить, что является агрегацией, используя разреженный индекс или нет. –

ответ

2

Да, агрегация MongoDB будет использовать подходящие разреженные индексы, за исключением случаев, если разреженный индекс вернет неполные результаты для определенного запроса.

Выдержка 2 в вопросе объясняет пример того, где разреженный индекс возвращает неполные результаты для определенного запроса. В случае, когда запрос сортирует в разреженном поле, но не фильтрует на нем, этот индекс не может быть использован, так как результаты будут неполными (документы, пропускающие это поле, будут неправильно исключены).

Другой случай, когда разреженный индекс не может быть использован, заключается в том, где вы фильтруете поле, но с таким запросом, как { x: { $exists: false } }, где разреженный индекс не будет содержать результаты сопоставления (поскольку он специально исключает их).

В вашем случае, как вы говорите, $match фильтрует на поле с разреженным индексом, разреженный индекс может быть использован, если индекс будет содержать полные результаты, например, вы проверяете равенство или используете оператор сравнения, например $gte и т. д., но не такой оператор, как $ne или { $exists: false }.

Вы можете подтвердить командой объяснения, даже без executionStats.

Из агрегации теста запроса с {$match:{a:4}} и без индекса поля a, коллекция сканирования выполняется:

"winningPlan" : { 
    "stage" : "COLLSCAN", 
    "filter" : { 
     "a" : { 
      "$eq" : 4 
     } 
    }, 
    "direction" : "forward" 
}, 

Из запроса агрегации теста с {$match:{b:4}} с разреженным-индексированным полем b, используются разреженный индекс:

"winningPlan" : { 
    "stage" : "FETCH", 
    "inputStage" : { 
     "stage" : "IXSCAN", 
     "keyPattern" : { 
      "b" : 1 
     }, 
     "indexName" : "b_1", 
     "isMultiKey" : false, 
     "isUnique" : false, 
     "isSparse" : true, 
     "isPartial" : false, 
     "indexVersion" : 1, 
     "direction" : "forward", 
     "indexBounds" : { 
      "b" : [ 
       "[4.0, 4.0]" 
      ] 
     } 
    } 
}, 

Для агрегации теста запроса с {$match:{b:{$exists:false}} на разреженных индексированные полях b (это будет возвращать неполные результаты с разреженный индекс b), коллекция сканирования выполняется:

"winningPlan" : { 
    "stage" : "COLLSCAN", 
    "filter" : { 
     "$not" : { 
      "b" : { 
       "$exists" : true 
      } 
     } 
    }, 
    "direction" : "forward" 
}, 
Смежные вопросы