如何过滤数组元素 [英] How to filter array elements

查看:108
本文介绍了如何过滤数组元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下MongoDB文档:

I have the following MongoDB document:

{
 _id: ObjectId(5), 
 items: [1,2,3,45,4,67,9,4]
}

我需要使用过滤后的项目(1、9、4)来获取该文档

I need to fetch that document with filtered items (1, 9, 4)

结果:

{
 _id: ObjectId(5), 
 items: [1,9,4]
}

我尝试了$ elemMatch投影,但是它只返回一项:

I've tried an $elemMatch projection but it returns only one item:

A.findById(ObjectId(5))
   .select({ items: { $elemMatch: {$in: [1, 9, 4]}}})
   .exec(function (err, docs) {
      console.log(doc); // { _id: ObjectId(5), items: [ 1 ] }
      done(err);
});

如何获取包含以下项目的文档:仅1,9,4?

How can I get the document with items: 1, 9, 4 only?

推荐答案

在现代版本的MongoDB(3.2+)中,您可以使用

In modern versions of MongoDB (3.2+) you can use the $filter operator to select a subset of an array field to return based on a specified condition. Returned elements will be in the original order from the field array.

mongo外壳中的示例:

db.items.aggregate([
    { $match : {
        _id: 5
    }},
    { $project: {
        items: {
            $filter: {
                input: "$items",
                cond: {
                    "$in": ["$$this", [1, 9, 4]]
                }
            }
        }
     }
}])

注意:因为此问题中的原始数组的值两次为4,所以$filter命令将返回两次出现的情况:

Note: because the original array in this question has the value 4 twice, the $filter command will return both occurrences:

{ "_id" : 5, "items" : [ 1, 4, 9, 4 ] }

对于仅返回唯一匹配项的替代方法,请可以使用$setIntersection运算符:

For an alternative approach which will only return the unique matching items, the $setIntersection operator could be used:

db.items.aggregate([
    { $match : {
        _id: 5
    }},        
    { $project: {
        items: {
            $setIntersection: ['$items', [1,4,9]] 
        }
    }}
])

这将返回:{ "_id" : 5, "items" : [ 1, 4, 9 ] }.

(以下为2012年9月的原始答案)

如果您希望文档操作在服务器端进行,则可以使用聚合MongoDB 2.2中的框架:

If you want the document manipulation to happen on the server side, you can use the Aggregation Framework in MongoDB 2.2:

db.items.aggregate(

  // Match the document(s) of interest
  { $match : {
     _id: 5
  }},

  // Separate the items array into a stream of documents
  { $unwind : "$items" },

  // Filter the array
  { $match : {
    items: { $in: [1, 9, 4] }
  }},

  // Group the results back into a result document
  { $group : {
     _id: "$_id",
     items: { $addToSet : "$items" }
  }}
)

结果:

{
    "result" : [
        {
            "_id" : 5,
            "items" : [
                9,
                4,
                1
            ]
        }
    ],
    "ok" : 1
}

这篇关于如何过滤数组元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆