【问题标题】:Find a document in a collection by eliminating the array object values having some flag通过消除具有某些标志的数组对象值来查找集合中的文档
【发布时间】:2015-10-27 20:26:18
【问题描述】:

考虑一个包含类似文档的集合(下面提到了虚拟值):

{
    id: "001",
    company: "abc",
    empDet: [
        {
            disableFlag: true,
            name: 'raj',
            age: 45,
            designation: 'clerk'
        },
        {
            disableFlag: false,
            name: 'ramya',
            age: 35,
            designation: 'manager'
        },
        {
            disableFlag: false,
            name: 'gabriel',
            age: 41,
            designation: 'asstManager'
        },
        {
            disableFlag: true,
            name: 'saran',
            age: 55,
            designation: 'attender'
        },
        {
            disableFlag: true,
            name: 'buela',
            age: 25,
            designation: 'cashier'
        }
    ],
    location: "delhi"
},
{
    id: "002",
    company: "xyz",
    empDet: [
        {
            disableFlag: true,
            name: 'ravi',
            age: 45,
            designation: 'consultant'
        },
        {
            disableFlag: true,
            name: 'reka',
            age: 35,
            designation: 'manager'
        },
        {
            disableFlag: false,
            name: 'geetha',
            age: 41,
            designation: 'asstManager'
        },
        {
            disableFlag: false,
            name: 'varun',
            age: 55,
            designation: 'attender'
        },
        {
            disableFlag: true,
            name: 'balu',
            age: 25,
            designation: 'clerk'
        }
    ],
    location: "mumbai"
},
{
    id: "003",
    company: "pqr",
    empDet: [
        {
            disableFlag: true,
            name: 'bobby',
            age: 45,
            designation: 'consultant'
        },
        {
            disableFlag: true,
            name: 'vinay',
            age: 35,
            designation: 'manager'
        },
        {
            disableFlag: true,
            name: 'faritha',
            age: 41,
            designation: 'asstManager'
        },
        {
            disableFlag: false,
            name: 'arun',
            age: 55,
            designation: 'attender'
        },
        {
            disableFlag: true,
            name: 'kayal',
            age: 25,
            designation: 'clerk'
        },
    ],
    location: "calcutta"
}

使用 node.js 和猫鼬,我想检索 xyz 公司详细信息,但 "empDet" 的值应该只有包含 disableFlag 的值为 true。例如,我期望的输出应该是:

{
  id: "002",
  company: "xyz",
  empDet: [
    {
      disableFlag: true,
      name: 'ravi',
      age: 45,
      designation: 'consultant'
    },
    {
      disableFlag: true,
      name: 'reka',
      age: 35,
      designation: 'manager'
    },
    {
      disableFlag: true,
      name: 'balu',
      age: 25,
      designation: 'clerk'
    }    
  ],
  location: "mumbai"
}

如何通过使用 node.js 和 mongoose 消除具有某些标志为 false 的数组对象值来查找或检索集合中的文档?

【问题讨论】:

  • 你应该为你的模型添加一个新属性,或者你在这个状态下检查查询结果。

标签: node.js mongodb mongoose


【解决方案1】:

在这种情况下,aggregation framework 中的 $redact 管道运算符应该适合您。这将递归地遍历文档结构,并根据对每个级别的指定条件的评估执行一些操作。这个概念可能有点难以理解,但以下示例说明了这一点:

Model.aggregate([
    { 
        "$match": { "company" : "xyz" }
    },
    { 
        "$redact": {
            "$cond": {
                "if": {
                    "$eq": [ "$disableFlag", false ] 
                },
                "then": "$$PRUNE",
                "else": "$$DESCEND"
            }
        }
    }
]).exec(function (err, results){
      // handle error
      console.log(results);
});

样本输出:

/* 0 */
{
    "result" : [ 
        {
            "_id" : ObjectId("562e1398bf03613b4ad1b541"),
            "id" : "002",
            "company" : "xyz",
            "empDet" : [ 
                {
                    "disableFlag" : true,
                    "name" : "ravi",
                    "age" : 45,
                    "designation" : "consultant"
                }, 
                {
                    "disableFlag" : true,
                    "name" : "reka",
                    "age" : 35,
                    "designation" : "manager"
                }, 
                {
                    "disableFlag" : true,
                    "name" : "balu",
                    "age" : 25,
                    "designation" : "clerk"
                }
            ],
            "location" : "mumbai"
        }
    ],
    "ok" : 1
}

-- 更新-- 如果您想填充属于 xyz 公司的员工的员工详细信息,您可以使用 populate 和最新版本的 mongoose,它能够在已完成的查询中递归填充相关文档添加。但这需要第二次查询,并且像这样使用不同的填充:

var pipeline = [
    { 
        "$match": { "company" : "xyz" }
    },
    { 
        "$redact": {
            "$cond": {
                "if": {
                    "$eq": [ "$disableFlag", false ] 
                },
                "then": "$$PRUNE",
                "else": "$$DESCEND"
            }
        }
    }
];
Model.aggregate(pipeline,
    function(err, results) {
        if (err) throw err;            
        Model.populate(results, {"path": "empDet.emp_id"}, function(err, results) {
            if (err) throw err;
            console.log(JSON.stringify(results, undefined, 4));
        });
    }
);

【讨论】:

  • 非常感谢您的回复。但是我忘了提到在 empDet(embedded) 中还会有一个字段,例如 emp_id,它将是字符串并且它引用另一个集合。因此,我还必须填充属于 xyz 公司的员工的员工详细信息(加入基于 emp_id 的集合)以及我之前的查询中提到的其他值(应该只有包含 disableFlag 为 true 的值)。很抱歉之前没有提到。(填充和聚合都应该使用,我怎样才能做到这一点?)
  • 感谢您的帮助,我能够同时使用聚合和填充。我得到了所需的输出。 Model.aggregate([ { "$match": { "company" : "xyz" } }, { "$redact": { "$cond": { "if": { "$eq": ["$disableFlag" , false ] }, "then": "$$PRUNE", "else": "$$DESCEND" } } } ]).exec(function (err, results){ Model.populate(results,{path:'empDet .emp_id'},function(error,op){ console.log(op); }); });
  • 不用担心。我已经更新了我的答案,因为我不知道您的数据库架构是什么样的,因此应该可以将您推向正确的方向。但是这个概念是在底层结果上调用 populate 方法,如果丢失,链接的文档应该会有所帮助。
  • 我是 stackoverflow.com 的新用户,我尝试接受您的解决方案,但只有在获得 15 名声望后,我的投票才会改变公开显示的帖子分数。但你的回复真的很有帮助。谢谢 Chridam
猜你喜欢
  • 1970-01-01
  • 2023-04-04
  • 2020-10-16
  • 2020-06-07
  • 1970-01-01
  • 1970-01-01
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多