是不是可以聚合从“查找并更新”返回的文档?

huangapple go评论61阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2023年3月15日 20:59:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/75745064.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定