2014-07-17 123 views
1

阵列内找到我有使用以下结构创建文档的schemea:MongoDB的聚集,值

{ 
    "_id" : "2014-07-16:52TEST", 
    "date" : ISODate("2014-07-16T23:52:59.811Z"), 
    "name" : "TEST" 
    "values" : [ 
     [ 
      1405471921000, 
      0.737121 
     ], 
     [ 
      1405471922000, 
      0.737142 
     ], 
     [ 
      1405471923000, 
      0.737142 
     ], 
     [ 
      1405471924000, 
      0.737142 
     ] 
    ] 
} 

在值,第一个指数是一个时间戳。我想要做的是查询特定的时间戳找到最接近的值($gte)。

我已经试过以下汇总查询:

[ 

     { "$match": { 
      "values": { 
       "$elemMatch": { "0": {"$gte": 1405471923000} } 
      }, 
      "name" : 'TEST' 
     }}, 

     { "$project" : { 
      "name" : 1, 
      "values" : 1 
     }}, 

     { "$unwind": "$values" }, 

     { "$match": { "values.0": { "$gte": 1405471923000 } } }, 

     { "$limit" : 1 }, 

     { "$sort": { "values.0": -1 } }, 

     { "$group": { 
      "_id": "$name", 
      "values": { "$push": "$values" }, 
     }} 



    ] 

这似乎是工作,但它不拉最接近的值。它似乎拉大了或大于或等于排序似乎没有得到应用,所以它会拉一个时间戳,在未来很远。

任何建议将是伟大的!

谢谢

回答

0

有几件事情错在这里的办法,即使它是一个公平的努力。你说得对,你需要$sort这里,但问题是你不能用数组“排序”内部元素。为了得到一个可以排序的值,你必须首先使用$unwind这个数组,否则它将不会在数组中排序。

你当然也不希望$limit在流水中。您可能会针对单个文档进行测试,但“限制”实际上会对管道中的整个文档集起作用。所以如果不止一个文件符合你的条件,那么它们将被扔掉。

您想要在此处执行的关键是在$group阶段使用$first,该阶段在您进行排序以获得所需的“最接近”元素后应用。

db.collection.aggregate([ 

    // Documents that have an array element matching the condition 
    { "$match": { 
     "values": { "$elemMatch": { "0": {"$gte": 1405471923000 } } } 
    }}, 

    // Unwind the top level array 
    { "$unwind": "$values" }, 

    // Filter just the elements that match the condition 
    { "$match": { "values.0": { "$gte": 1405471923000 } } }, 

    // Take a copy of the inner array 
    { "$project": { 
     "date": 1, 
     "name": 1, 
     "values": 1, 
     "valCopy": "$values" 
    }}, 

    // Unwind the inner array copy 
    { "$unwind": "$valCopy" }, 

    // Filter the inner elements 
    { "$match": { "valCopy": { "$gte": 1405471923000 } }}, 

    // Sort on the now "timestamp" values ascending for nearest 
    { "$sort": { "valCopy": 1 } }, 

    // Take the "first" values 
    { "$group": { 
     "_id": "$_id", 
     "date": { "$first": "$date" }, 
     "name": { "$first": "$name" }, 
     "values": { "$first": "$values" }, 
    }}, 

    // Optionally push back to array to match the original structure 
    { "$group": { 
     "_id": "$_id", 
     "date": { "$first": "$date" }, 
     "name": { "$first": "$name" }, 
     "values": { "$push": "$values" }, 
    }} 
]) 

这会产生你的文档只有“最近”时间戳值匹配的原始文件格式:

{ 
    "_id" : "2014-07-16:52TEST", 
    "date" : ISODate("2014-07-16T23:52:59.811Z"), 
    "name" : "TEST", 
    "values" : [ 
      [ 
        1405471923000, 
        0.737142 
      ] 
    ] 
}