Mongoose 通过 _id 查询对象数组
Posted
技术标签:
【中文标题】Mongoose 通过 _id 查询对象数组【英文标题】:Mongoose query array of objects by _id 【发布时间】:2017-08-15 07:14:47 【问题描述】:我有以下架构:
const userSchema = new Schema(
local:
email: type: String, unique: true, lowercase: true, trim: true, required: true,
password: type: String, required: true,
,
Items: [
name: type: String, trim: true,
createdAt: type: Date, default: Date.now, select: false
]
);
如何根据从 url 参数接收到的特定 _id 查询 'Items'
(包含对象数组)?
我有许多不同的变体,包括下面显示的一个,但它们似乎都返回包含所有对象的 Items 数组,而不仅仅是一个与 id 匹配的对象?
User.findById(req.user.id, , "Items._id": req.params.id, (err, result) => ...
【问题讨论】:
使用projection。类似User.findOne(_id:req.user.id, "Items._id": req.params.id,, "Items.$": 1, (err, result) => ...
仍然返回所有的项目,而不是一个单一的
可能是我的猫鼬查询不正确。您可以验证它在 mongo shell 中运行它。 db.users.findOne(_id:req.user.id, "Items._id": req.params.id,"Items.$": 1)
。它将返回一个项目值。我会尝试找到正确的猫鼬查询。
是的,它可以在 mongo shell 中工作,我应该在 mongoose 中使用它吗?还是有更有效的方法来编写它?谢谢
Np。是的,如果你知道如何转换为猫鼬。我相信这是猫鼬中的正确查询。 User.findOne(_id:req.user.id, "Items._id": req.params.id,"Items.$": 1, (err, result) => ...
【参考方案1】:
您必须使用$projection
来访问嵌入式数组中的元素。查询部分找到匹配的数组元素并将占位符 $
替换为匹配元素的数组索引,而投影部分 $
现在将使用占位符值将数组元素投影为响应。
Mongo Shell 变体:db.users.findOne(_id:req.user.id, "Items._id": req.params.id,"Items.$": 1)
猫鼬变种:User.findOne(_id:req.user.id, "Items._id": req.params.id,"Items.$": 1, (err, result) => ...
【讨论】:
你能告诉我你的查询吗?投影中不允许混合排除和包含路径,_id
字段除外。
它与您提供的相同,只是第二个对象在 "Items.$":1 前面包含 "_id":0 ,它工作正常,但我将如何修改这个整体查询以获得从结果中去掉 createdAt 属性?我想我可以在 findOne 上调用lea() 将其转换为常规对象,然后使用 delete user.Items[0].createdAt,但是在数据库端有什么方法吗?
不,你不能像我说的那样。您不能在同一投影中同时包含包含 ("Items.$": 1
) 和排除路径 ("Items.createdAt": 0
)。你必须在猫鼬方面照顾好它。更多这里docs.mongodb.com/v3.2/tutorial/…
对不起,我是 mongo 和 mongooose 的新手,在 findOne 上调用lea() 并使用 delete user.Items[0].createdAt 是解决这个问题的有效方法吗?或者有没有更有效的方法来做到这一点?
我不是猫鼬方面的专家,但如果你关心性能,我个人认为这根本不是问题,那么看起来精益是你所需要的。这提供了有关精益 ***.com/questions/7503450/… 和 ***.com/questions/15097375/… 的更多信息。我希望这能让你平静一点。【参考方案2】:
您要做的是查询子文档。查看http://mongoosejs.com/docs/subdocs.html
你可以这样做:
User.findById(req.user.id, (err, user) =>
let item = user.Items.id(req.params.id);
);
【讨论】:
我正在寻找一种在数据库端进行操作的方法,而不是在应用程序级别 我没有使用子文档,我只有一个模式,“项目”只是一个名称,就像“本地”一样 @linasmnew 是的,这些是子文档——这就是它们有 _id 的原因。除非您指定不需要 ID,否则它会在那里。 Mongo 中的所有对象都是文档。 谢谢 不知道,user.Items.id中的'id'是指什么?因为当我在终端内查询数据库时,只有_id DocumentArrays 有一个特殊的 id 方法可以通过它的 _id 来查找一个文档。 mongoosejs.com/docs/subdocs.html以上是关于Mongoose 通过 _id 查询对象数组的主要内容,如果未能解决你的问题,请参考以下文章
使用 Mongoose 从 JSON 对象数组中查询具有匹配 ID 的集合
Mongoose:通过 findOneAndUpdate 查询使用对象数组的总和更新根数据属性不起作用
从 Mongoose Find() 查询向对象数组添加属性 [重复]