如何过滤数组元素

时间:2012-09-26 03:02:00

标签: node.js mongodb express mongoose

我有以下MongoDB文档:

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

我需要使用过滤的项目(1,9,4)

获取该文档

结果:

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

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

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?

3 个答案:

答案 0 :(得分:4)

A.items = A.items.filter( function(i) {return i == 1 || i == 9 || i == 4} );

答案 1 :(得分:3)

在现代版本的MongoDB(3.2+)中,您可以使用$filter operator选择要根据指定条件返回的数组字段的子集。返回的元素将按字段数组的原始顺序排列。

mongo shell中的示例:

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

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

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

对于只返回唯一匹配项的替代方法,可以使用$setIntersection operator

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

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

(2012年9月起的原始答案)

如果您希望在服务器端进行文档操作,可以使用MongoDB 2.2中的Aggregation Framework

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
}

答案 2 :(得分:0)

在node.js应用中使用下划线:

npm install underscore

var _ = require('underscore');

您可以使用数组的交集功能:

 intersection_.intersection(*arrays)

计算所有数组交集的值列表。结果中的每个值都存在于每个数组中。

_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2]

http://documentcloud.github.com/underscore/#intersection