微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

node.js – 从匹配属性的数组中获取所有结果

参见英文答案 > Retrieve only the queried element in an object array in MongoDB collection                                    11个
我知道如何使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 举报,一经查实,本站将立刻删除。

相关推荐