【问题标题】:Update Object Inside the Array of object in a mongoose document with projection or select使用投影或选择更新猫鼬文档中对象数组内的对象
【发布时间】:2020-08-08 15:52:30
【问题描述】:

我正在尝试更新文档中的对象

文档:猫

{
        "_id": "5e5cb512e90bd40017385305",
        "type": "cat"
        "history": [
          {
            "id": "randomID",
            "content": "xyz",
          },
          {
            "id": "randomID2",
            "content": "abc",
          }
        ]
}

选择和更新历史数组中的对象的代码:

const editHistory = async (_, { input }, ctx) => {
  let query = { _id: input.catId, "history.id": input.historyId };
  let update = { $set: { "history.$": input.history } };
  let options = {
    new: true,
    fields: { history: { $elemMatch: { id: "randomID" } } }
  };

  let cat = await ctx.models.cats.findOneAndUpdate(query, update, options);

  return cat;
};

输入有以下值

input: {
catId: "5e5cb512e90bd40017385305",
historyId: "randomID",
history: {
id: "randomID",
content: "new content"
}}

我尝试使用 Projection,我使用 select 将其更改为字段,可在 mongoose 文档中找到。 我仍然无法更新这些值。我查询或选择子字段的方式有什么问题吗?

【问题讨论】:

  • id(文档)或_id(查询)?
  • Cat 文档的 _id 和历史数组对象的 id
  • 当您使用相同的查询运行findOne 时会发生什么?
  • 它只是返回 Cat 文档
  • @mickl 有办法解决这个问题吗?

标签: database mongodb mongoose mongodb-query mongoose-schema


【解决方案1】:

通过查看操作符($set)和选项(new,fields)的更多细节找到了解决方案。

问题:

const editHistory = async (_, { input }, ctx) => {
  let query = { _id: input.catId, "history.id": input.historyId };
  let update = { $set: { "history.$": input.history } };
  let options = {
    // using new option would return the new document
    new: true, 
    /* using fields option would select the based on the given key, but using new: 
       true with fields will throw error: 'cannot use a positional projection and 
   return the new document'
   */
    fields: { history: { $elemMatch: { id: "randomID" } } } 
  };

  let cat = await ctx.models.cats.findOneAndUpdate(query, update, options);

  return cat;
};

下面的这篇文章回答了 *error: 'cannot use a positional projection and return the new document' 的问题。

https://stackoverflow.com/a/46064082/5492398

最终解决方案:

const editHistory = async (_, { input }, ctx) => {
  let query = { _id: input.catId, "history.id": input.historyId };
  let update = { $set: { "history.$": input.history } };
  let options = {
    new: true
  };

  let cat = await ctx.models.cats.findOneAndUpdate(query, update, options);

  return cat;
};

删除字段选项,因为在原子修改之前我不需要未修改的选择,所以解决了这个问题。

【讨论】:

    猜你喜欢
    • 2022-08-18
    • 2020-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-03
    • 1970-01-01
    • 1970-01-01
    • 2021-08-11
    相关资源
    最近更新 更多