В ссылке из поста Дмайта Мерримана упоминается использование ключа пути и сопоставление регулярных выражений
{
path : "a.b.c.d.e.f"
}
Еще один способ сделать это - с массивами
{
path : ["a", "b", "c", "d", "e", "f"]
}
db.test.ensureIndex({path: 1})
это должно сделать это довольно быстро.
если каждый узел может быть только в одном пути, вам не нужно беспокоиться о том, где он находится в списке
db.test.find({path: "a"})
найдет всех детей "a"
Вместо имен путей я бы, вероятно, использовал _id узлов.
Обновление
- Остерегайтесь одной вещи - индекс может содержать только один массив.
Будьте осторожны, используя объяснения в ваших запросах
db.test.find ({путь: {$ in: ["a", "b"]})
дает вам
db.test.find({path: {$in: ["a", "b"]}}).explain()
{
"cursor" : "BtreeCursor path_1 multi",
"nscanned" : 2,
"nscannedObjects" : 2,
"n" : 1,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : true,
"indexOnly" : false,
"indexBounds" : {
"path" : [
[
"a",
"a"
],
[
"b",
"b"
]
]
}
}
но
db.test.find({path: {$all: ["a", "b"]}}).explain()
{
"cursor" : "BtreeCursor path_1",
"nscanned" : 1,
"nscannedObjects" : 1,
"n" : 1,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : true,
"indexOnly" : false,
"indexBounds" : {
"path" : [
[
"a",
"a"
]
]
}
}
использует только первый элемент, а затем сканирует все подходящие результаты для b.
Если a является вашим корневым элементом или присутствует в большинстве ваших записей, вы выполняете почти полное сканирование записей вместо эффективного запроса индекса.