Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 仅当条件为true时,如何使用$filter(聚合)选择数组的某些字段?_Node.js_Mongodb_Mongoose_Aggregation Framework - Fatal编程技术网

Node.js 仅当条件为true时,如何使用$filter(聚合)选择数组的某些字段?

Node.js 仅当条件为true时,如何使用$filter(聚合)选择数组的某些字段?,node.js,mongodb,mongoose,aggregation-framework,Node.js,Mongodb,Mongoose,Aggregation Framework,我来告诉你我到底想要什么。假设我有下面两个XYZ模型的文档 [ { "_id" : ObjectId("59ef8786e8c7d60552139ba9"), "name" : "s1", "email" : "one@one.com", "mobileNumber" : "910123456989", "verificationStatus" : true, "activities" : [

我来告诉你我到底想要什么。假设我有下面两个XYZ模型的文档

[
    {
        "_id" : ObjectId("59ef8786e8c7d60552139ba9"),
        "name" : "s1",
        "email" : "one@one.com",
        "mobileNumber" : "910123456989",
        "verificationStatus" : true,
        "activities" : [ 
            {
                "name" : "a1",
                "_id" : ObjectId("59ef8786e8c7d60552139bae"),
                "type" : 0,
                "level" : null,
                "verificationStatus" : true
            }, 
            {
                "name" : "a2",
                "_id" : ObjectId("59ef8786e8c7d60552139bad"),
                "type" : 0,
                "level" : null,
                "verificationStatus" : false
            } 
        ],
        "address" : {
            "line1" : "asd",
            "line2" : "asd",
            "city" : "sd",
            "state" : "sd",
            "country" : "asd",
            "landmark" : "sdsa",
            "pincode" : "560090"
        },
        "__v" : 0
    },
    {
        "_id" : ObjectId("59ef8786e8c7d60552139ba9"),
        "name" : "s1",
        "email" : "one@one.com",
        "mobileNumber" : "919876543210",
        "verificationStatus" : true,
        "activities" : [ 
            {
                "name" : "b1",
                "_id" : ObjectId("59ef8786e8c7d60552139bae"),
                "level" : null,
                "type" : 0,
                "verificationStatus" : true
            }, 
            {
                "name" : "b2",
                "_id" : ObjectId("59ef8786e8c7d60552139bad"),
                "level" : null,
                "type" : 0,
                "verificationStatus" : false
            }
        ],
        "address" : {
            "line1" : "asd",
            "line2" : "asd",
            "city" : "sd",
            "state" : "sd",
            "country" : "asd",
            "landmark" : "sdsa",
            "pincode" : "560090"
        },
        "__v" : 0
    }
]
现在,我只需要文档中的
name
mobileNumber
activities.name
,其中verificationStatus为true,我不想要我想要的所有activities.name仅当
activities.VariationStatus
为true时

我可以获取所有文档的列表,其中
VariationStatus
为真,并且
活动。VariationStatus
为真,但我无法从
活动中仅选择必填字段(
活动。名称

我目前的代码是:

XYZ.aggregate(
    [
        { $match: { verificationStatus: true } },
        {
            $project: {
                name: 1,
                coverImage: 1,
                location: 1,
                address: 1,
                dist: 1,
                activities: {
                    $filter: {
                        input: "$activities",
                        as: "activity",
                        cond: {
                            $eq: ["$$activity.verificationStatus", true]
                        }
                    }
                }
            }
        }], function (err, list) {
            if (err) {
                reject(err);
            }
            else {
                resolve(list);
            }
        });
实际上,您需要“更改”返回的数组元素,因为只有“选择”匹配的数组元素:

将返回:

{
        "_id" : ObjectId("59ef8786e8c7d60552139ba9"),
        "name" : "s1",
        "mobileNumber" : "910123456989",
        "activities" : ["a1"]
}
{
        "_id" : ObjectId("59ef8786e8c7d60552139ba9"),
        "name" : "s1",
        "mobileNumber" : "919876543210",
        "activities" : ["b1"]
}
还请注意,中的
“cond”
可以缩短,因为它已经是一个
布尔值

如果只需要属性为
“name”
的“对象”,则只返回指定的键:

XYZ.aggregate(
    [
        { $match: { verificationStatus: true } },
        {
            $project: {
                name: 1,
                mobileNumber: 1,
                activities: {
                  $map: {
                    input: {
                      $filter: {
                          input: "$activities",
                          as: "activity",
                          cond: "$$activity.verificationStatus"
                      }
                    },
                    "as": "a",
                    "in": {
                      "name": "$$a.name"
                    }
                  }
                }
            }
        }], function (err, list) {
        ...
返回为:

{
        "_id" : ObjectId("59ef8786e8c7d60552139ba9"),
        "name" : "s1",
        "mobileNumber" : "910123456989",
        "activities" : [{ "name": "a1" }]
}
{
        "_id" : ObjectId("59ef8786e8c7d60552139ba9"),
        "name" : "s1",
        "mobileNumber" : "919876543210",
        "activities" : [{ "name": "b1" }]
}
如果您确实知道您正在匹配数组中的“一”元素,那么如果您有MongoDB 3.4,则可以使用with

{ "$project": {
  "name": 1,
  "mobileNumber": 1,
  "activities": {
    "$arrayElemAt": [
      "$activities.name",
      { "$indexOfArray": [ "$activities.verificationStatus", true ] }
    ]
  }
}}
结果会有点不同,因为它是一个奇异值,而不是一个数组:

{
        "_id" : ObjectId("59ef8786e8c7d60552139ba9"),
        "name" : "s1",
        "mobileNumber" : "910123456989",
        "activities" : "a1"
}
{
        "_id" : ObjectId("59ef8786e8c7d60552139ba9"),
        "name" : "s1",
        "mobileNumber" : "919876543210",
        "activities" : "b1"
}
{
        "_id" : ObjectId("59ef8786e8c7d60552139ba9"),
        "name" : "s1",
        "mobileNumber" : "910123456989",
        "activities" : "a1"
}
{
        "_id" : ObjectId("59ef8786e8c7d60552139ba9"),
        "name" : "s1",
        "mobileNumber" : "919876543210",
        "activities" : "b1"
}