Javascript 更新子文档数组对象

Javascript 更新子文档数组对象,javascript,mongodb,mongoose,Javascript,Mongodb,Mongoose,我想用findByIdAndUpdate by parent id和subdoc object id更新subdoc数组的一个对象。执行此代码时,我遇到以下错误: The positional operator did not find the match needed from the query. 当我使用带有过滤器参数的updateOne时,它可以工作。但我希望更新后的文档以json for rest api的形式返回 有没有办法获得更新的文档 我的代码: Subject.findByI

我想用findByIdAndUpdate by parent id和subdoc object id更新subdoc数组的一个对象。执行此代码时,我遇到以下错误:

The positional operator did not find the match needed from the query.
当我使用带有过滤器参数的updateOne时,它可以工作。但我希望更新后的文档以json for rest api的形式返回

有没有办法获得更新的文档

我的代码:

Subject.findByIdAndUpdate(
  { _id: req.params.subjectId, "bookmarks._id": req.params.bookmarkId },
  {
    $set: {
      "bookmarks.$.uri": req.body.uri
    }
  },
  { new: true }
)
模式:

{
    "_id": "5e7fbfc05ff6be1446b51af7",
    "user_id": "5e7e68c3fd5e9404ce6a14a3",
    "title": "Hello World",
    "date": "2020-03-28T21:21:04.434Z",
    "bookmarks": [
        {
            "date": "2020-03-28T21:21:20.806Z",
            "_id": "5e7fbfd05ff6be1446b51afa",
            "uri": "lorem ipsum"
        },
        {
            "date": "2020-03-28T21:21:21.433Z",
            "_id": "5e7fbfd15ff6be1446b51afb",
            "uri": "lorem ipsum"
        }
    ]
}
您应该使用:

由于您的
req.params.subjectId
req.params.bookmarkId
是字符串,数据库中的相应字段将为
ObjectId()
-因此使用以下代码将字符串转换为ObjectId():

const mongoose = require('mongoose');
const _id = mongoose.Types.ObjectId(req.params.subjectId);
const bookmarkId = mongoose.Types.ObjectId(req.params.bookmarkId);

Subject.findOneAndUpdate(
  { _id: _id, "bookmarks._id": bookmarkId },
  {
    $set: {
      "bookmarks.$.uri": 'new new'
    }
  },
  { new: true }
)

您的问题应该是mongoose的
。findByIdAndUpdate()
只接受一个字符串值并在内部将其转换为
{id:ObjectId(req.params.subjectId)}
使用
.findOneAndUpdate()
,它只是一种包装器。

谢谢,现在它可以工作了。它也可以处理字符串,但为了安全起见,我采纳了您的想法,将查询的字符串转换为对象ID。:)@mnlfischer:不,您不必从string转换为ObjectId(),如果您的数据库将这些字段作为字符串,转换就是要确保类型匹配。经过一些研究,我将使用mongoose.types.ObjectId.isValid(subjectId)来检查传递的参数是否是有效的对象id。我没有定义显式id,所以我为每个主题自动生成一个对象id。谢谢分享你的想法!