Mongo DB为所有子对象

时间:2015-05-27 10:20:18

标签: mongodb

我还是MongoDB的新手,我无法实现以下目标。 这是我必须处理的一个集合中的一个对象:

 {
     "_id" : ObjectId("5306ad28e4b04bd6667b03bf"),
     "name" : "FOOBAR",
     "Items" : [
         {
             "price" : 0,
             "currency" : "EUR",
             "expiryDate" : ISODate("2014-03-15T23:00:00Z"),
         },
         {
             "price" : 0,
             "currency" : "EUR",
             "expiryDate" : ISODate("2015-03-15T23:00:00Z"),
         },
         {
             "currency" : "EUR",
             "expiryDate" : ISODate("2015-04-16T23:00:00Z"),
         }, ...}

我现在需要找到对象,其中时间戳" expiryDate"对于" Items"中的所有子对象小于某个值(ISODate)。

以下是它的尝试:

1. first try

db.COLL.findOne({"Items.expiryDate": { $lt : ISODate("2015-02-10T00:00:00.000Z") }}));"

这也会返回只有一个" expiryDate"不太好。

  1. 第二次尝试

    db.COLL.findOne({"Items": { $all : [ "$elemMatch" : { expiryDate: { $lt: ISODate(\"2015-02-10T00:00:00.000Z\") }} ] }}));"
    
  2. 每个查询只向我提供某些所有子对象的时间戳小于特定时间的项目。

    请帮我写这个查询!!

2 个答案:

答案 0 :(得分:1)

您可以使用 aggregation Framework 来实现此目标。

使用$size运算符,我们可以找到将在聚合后期使用的Items的大小。 $unwind解构Items数组,以便我们可以在下一个$match阶段对单个项目应用条件。

$group阶段,我们计算已过滤的Items的大小,并使用$cmp运算符将其与原始size进行比较。这样做是为了识别所有子文档-documents小于Date条件中提供的$match。'

db.Coll.aggregate([
    {'$project': {'name': 1, 'size': {'$size': '$Items'},'Items': 1}},
    {'$unwind': '$Items'},
    {'$match':  {'Items.expiryDate': { $lt: ISODate("2015-03-15T23:40:00.000Z")}}},
    {'$group': { '_id': '$_id','Items': { '$push': '$Items'},'size':{'$first': '$size'}, 'newsize': {'$sum':1}}},
    {'$project': {'cmp_value': { $cmp : ['$size', '$newsize']},'name' :1 ,'Items': 1}},
    {'$match': {'cmp_value': 0}}
])

答案 1 :(得分:0)

尽管这是一个非常老的问题,但让我为他人写评论。

  

db.collection.findOne

将仅返回一条记录。相反,您应该使用

  

db.collection.find

希望这会有所帮助!