英文:
Is it possible to aggregate document returning from "find and update"?
问题
假设我有两个如下的集合:
学生
{
  "_id": "1234",
  "name": "Theodo"
}
卡片
{
  "student_id": "1234",
  "given_date": "11.10.2019"
}
然后我需要像这样更新学生:
db.students.find_one_and_update({"_id": "1234"}, {"$set":{"name": "Matt"}}, return_document=ReturnDocument.AFTER)
这很酷,返回这样:
[
    {
      "_id": "1234",
      "name": "Matt"
    }
]
但是想象一下 UI 需要这样的信息:
[
  {
    "_id": "1234",
    "card_given_date": "11.10.2019",
    "name": "Matt"
  }
]
所以我需要通过聚合来检索它:
db.students.aggregate([
  {
    "$lookup": {
      "from": "cards",
      "localField": "_id",
      "foreignField": "student_id",
      "as": "student_card"
    }
  },
  {
    "$unwind": "$student_card"
  },
  {
    "$set": {
      "card_given_date": "$student_card.given_date"
    }
  },
  {
    "$unset": "student_card"
  }
])
测试聚合: https://mongoplayground.net/p/UlTGnXA2Rkx
我的问题是:我必须先更新,然后通过聚合来检索它。如果我可以在update操作后获取文档,是否有什么我可以做的来聚合返回的文档,以便我摆脱第二个retrieve操作?
英文:
Imagine I have two collections as below:
Students
{
  "_id": "1234",
  "name": "Theodo"
}
Card
{
  "student_id": "1234",
  "given_date": "11.10.2019"
}
And then I need to update the student like this;
db.students.find_one_and_update({"_id": "1234"}, {"$set":{"name": "Matt"}}, return_document=ReturnDocument.AFTER)
This is cool and it returns this;
[
    {
      "_id": "1234",
      "name": "Matt"
    }
]
But imagine the UI needs the information like this;
[
  {
    "_id": "1234",
    "card_given_date": "11.10.2019",
    "name": "Matt"
  }
]
So I need to retrieve it with an aggregation;
db.students.aggregate([
  {
    "$lookup": {
      "from": "cards",
      "localField": "_id",
      "foreignField": "student_id",
      "as": "student_card"
    }
  },
  {
    "$unwind": "$student_card"
  },
  {
    "$set": {
      "card_given_date": "$student_card.given_date"
    }
  },
  {
    "$unset": "student_card"
  }
])
test aggregation: https://mongoplayground.net/p/UlTGnXA2Rkx
And my question is; I have to update, then retrieve it with an aggregation. If I can get the document after update operation, is there anything I can do to aggregate the returned document, so that I get rid of second retrieve operation?
答案1
得分: 1
你理论上可以这样做,如果你运行的是 MongoDB 版本大于 5.1。
newDoc = db.students.find_one_and_update(
    { "_id": "1234" },
    { "$set": { "name": "Matt" } },
    { "returnNewDocument": True }
)
db.aggregate([
    { "$documents": [newDoc] },
    {
        "$lookup": {
            "from": "cards",
            "localField": "_id",
            "foreignField": "student_id",
            "as": "student_card"
        }
    },
    { "$unwind": "$student_card" },
    {
        "$set": {
            "card_given_date": "$student_card.given_date",
            "student_card": "$$REMOVE"
        }
    }
])
英文:
In principle you can do this, if you run MongoDB version > 5.1
let newDoc = db.students.findOneAndUpdate(
   { _id: "1234" },
   { $set: { "name": "Matt" } },
   { returnNewDocument: true }
)
db.aggregate([
   { $documents: [newDoc] },
   {
      $lookup: {
         from: "cards",
         localField: "_id",
         foreignField: "student_id",
         as: "student_card"
      }
   },
   { $unwind: "$student_card" },
   {
      $set: {
         card_given_date: "$student_card.given_date",
         student_card: "$$REMOVE"
      }
   }
])
But I don't know whether db.aggregate([ { $documents: ... } ]) is supported with python.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论