我知道如何使MongoDB基于这样的数组找到一行:
useritems.find({userid: useridhere,"items.id": idhere})
但是,我将如何搜索并获取所有激活的项目,或者根据项目属性获取所有项目?
例如:
useritems.find({userid: useridhere,"items.activated": true})
这是我的项目架构:
var userItemsSchema = new Schema({ userid : String,items: [ { id: {type: Number,default: 1},activated: { type: Boolean,default: false},endtime : {type: Number,default: 0},},],}); module.exports = mongoose.model('useritems',userItemsSchema);
解决方法
$filter
:
useritems.aggregate([ { "$match": { "userid": ObjectId(useridhere),"items.activated": true }},{ "$addFields": { "items": { "$filter": { "input": "$items","as": "i","cond": "$$i.activated" } } }} ],(err,results) => { });
注意到聚合框架中的值为useridhere,mongoose通常允许您传入“字符串”,并将该字符串“自动”转换为ObjectId值. This does not happen in the aggregation frameworkIssue#1399,因为它可能会改变所采取行动的文件的“形状”,因此不能应用“架构”.
所以你可能想从核心驱动程序中导入它:
const ObjectId = require('mongodb').ObjectID;
然后,您可以手动“转换”值.
当然,如果这个值实际上是从另一个mongoose对象而不是req.params或类似对象中检索的,那么它应该是ObjectId类型.
你为此使用.aggregate()的原因是因为“标准投影”只匹配一个元素.即:
useritems.find({ userid: useridhere,"items.activated": true }) .select('items.$') .exec((err,items) => { });
这里位置$运算符返回“匹配”元素,但只返回“第一”匹配.
所以在你想要“多个”匹配的地方你会使用$filter
,这比早期版本的MongoDB更有效,因为早期版本的MongoDB要求你首先使用$unwind
数组.
$unwind
运算符只应用于现代版本(通过MongoDB 2.4的任何内容),如果您确实想要在数组中使用“值”进行操作,例如$group
,其中该值表示为“分组键” .它在其他情况下的使用通常是一个“巨大的性能问题”,除了直接遵循$lookup
管道阶段,它确实有一个特殊的重要用例.
否则最好避免.请改用$filter
.
NOTE: The 07008 pipeline stage allows you to “overwrite” a single element without specifying all the other fields. If your MongoDB does not support this operator,use 07009 instead and specify all fields explicitly. i.e:
{ "$project": { "userid": 1,"items": { "$filter": { "input": "$items","cond": "$$i.activated" } } }}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。