У меня есть документы, представляющие папки. Я хотел бы сопоставить все родительские папки, если они есть.

{"_id":{"$oid":"5f8c406fc8c88110e0d927f2"},"name":"A"}
{"_id":{"$oid":"5f8c406fc8c88110e0d927f3"},"parentFolderId":"5f8c406fc8c88110e0d927f2","name":"B"}

Даже если отношения родитель-потомок более глубокие, для A мне нужна пустая родительская папка , а для B родительская папка A < / сильный>. Я попытался использовать для этого GraphLookup, но он не работает (каждый parentFolder пуст), и я не знаю, что мне не хватает:

db.folders.aggregate([
    {
        $addFields: {
            convertedId: { $toString: "$_id" }
        }
    },
    {
        $graphLookup: {
            from: "folders",
            startWith: "$parentFolderId",
            connectFromField: "parentFolderId",
            connectToField: "convertedId",
            as: "parentFolder",
            maxDepth: 0,
        }
    }
])

Если я переверну startWith, connectFromField, connectToFields соответственно, я получу реверс того, что мне нужно, A имеет массив, содержащий B, B имеет ничего такого.

Редактировать:

При нерабочем поиске я получаю следующий результат:

{ "_id" : ObjectId("5f8c406fc8c88110e0d927f2"), "name" : "A", "convertedId" : "5f8c406fc8c88110e0d927f2", "parentFolder" : [ ] }
{ "_id" : ObjectId("5f8c406fc8c88110e0d927f3"), "parentFolderId" : "5f8c406fc8c88110e0d927f2", "name" : "B", "convertedId" : "5f8c406fc8c88110e0d927f3", "parentFolder" : [ ] }

Мне нужно что-то вроде:

{ "_id" : ObjectId("5f8c406fc8c88110e0d927f2"), "name" : "A", "convertedId" : "5f8c406fc8c88110e0d927f2", "parentFolder" : [ ] }
{ "_id" : ObjectId("5f8c406fc8c88110e0d927f3"), "parentFolderId" : "5f8c406fc8c88110e0d927f2", "name" : "B", "convertedId" : "5f8c406fc8c88110e0d927f3", "parentFolder" : [ { "_id" : ObjectId("5f8c406fc8c88110e0d927f2"), "name" : "A", "convertedId" : "5f8c406fc8c88110e0d927f2" } ] }

Единственное отличие, которое я вижу в официальном примере "reportsTo", заключается в том, что я использую поле идентификатора для сопоставления документов, но это не должно быть проблемой, поскольку я не использую ObjectID: https://docs.mongodb.com/manual/reference/operator/aggregation/graphLookup/

2
Peter 18 Окт 2020 в 23:55

1 ответ

Лучший ответ

Пусть это то, что вы ищете. Мне не требовалось дополнительное поле convertedId. Так что я не добавил этого. Если хочешь, могу добавить и это. Но я думаю, что это будет лишняя информация.

db.collection.aggregate([
  {
    $graphLookup: {
      from: "collection",
      startWith: {
        $toObjectId: "$parentFolderId"
      },
      connectFromField: "parentFolderId",
      connectToField: "_id",
      as: "parentFolder",
      maxDepth: 0,
      
    }
  }
])

Ссылка на Mongo Playground

1
wak786 19 Окт 2020 в 09:29