MongoDB骨料

MongoDB骨料,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,这是我的文档结构: { "_id":ObjectId("548eb9fe8ad582f2f9976973"), "RECNUM":"1008", "ART_NR":"1014", "ART_NRA":"10010700", "ART_BEZ":{ }, "BES1":{ }, "markings":[ ], "prices":[ { "DATUM_VON":"2011-04-01", "DATUM_BIS":"", "MENG_BETR_BIS

这是我的文档结构:

{  
"_id":ObjectId("548eb9fe8ad582f2f9976973"),
"RECNUM":"1008",
"ART_NR":"1014",
"ART_NRA":"10010700",
"ART_BEZ":{  },
"BES1":{  },
"markings":[  ],
"prices":[  
  {  
     "DATUM_VON":"2011-04-01",
     "DATUM_BIS":"",
     "MENG_BETR_BIS":"1.0000",
     "PROZ_BETR":"4.2000"
  },
  {  
     "DATUM_VON":"2011-04-01",
     "DATUM_BIS":"",
     "MENG_BETR_BIS":"250.0000",
     "PROZ_BETR":"3.5000"
  },
  {  
     "DATUM_VON":"2011-04-01",
     "DATUM_BIS":"",
     "MENG_BETR_BIS":"500.0000",
     "PROZ_BETR":"3.4000"
  },
  {  
     "DATUM_VON":"2011-04-01",
     "DATUM_BIS":"",
     "MENG_BETR_BIS":"1000.0000",
     "PROZ_BETR":"3.3000"
  },
  {  
     "DATUM_VON":"2011-04-01",
     "DATUM_BIS":"",
     "MENG_BETR_BIS":"2500.0000",
     "PROZ_BETR":"3.2000"
  },

  {  
     "DATUM_VON":"2012-09-01",
     "DATUM_BIS":"",
     "MENG_BETR_BIS":"1.0000",
     "PROZ_BETR":"5.4000"
  },
  {  
     "DATUM_VON":"2012-09-01",
     "DATUM_BIS":"",
     "MENG_BETR_BIS":"250.0000",
     "PROZ_BETR":"4.5000"
  },
  {  
     "DATUM_VON":"2012-09-01",
     "DATUM_BIS":"",
     "MENG_BETR_BIS":"500.0000",
     "PROZ_BETR":"4.3500"
  },
  {  
     "DATUM_VON":"2012-09-01",
     "DATUM_BIS":"",
     "MENG_BETR_BIS":"1000.0000",
     "PROZ_BETR":"4.2000"
  },
  {  
     "DATUM_VON":"2012-09-01",
     "DATUM_BIS":"",
     "MENG_BETR_BIS":"2500.0000",
     "PROZ_BETR":"4.1000"
  }
] }

我需要在prices数组中提取包含max date值的文档。因此,在本例中,所有以2012-09-01为值的文档(4)

我试过这个:

 db.products.aggregate([
   { $match: {RECNUM: '1008'}},
   {"$unwind": "$prices"},
   {$match: { "$max": "$prices.DATUM_VON"}}
 ]);
但是这会抛出一个错误,因为我想我不能在$match中使用$max操作符。
如何实现这一点?

虽然已经提到,您确实应该将“日期”类型更改为实际的BSON日期而不是字符串,但至少它是一个“词法”字符串,因此对于比较是有效的

你真的想要比你最初的尝试更复杂一点的东西。关键是您需要在数组中找到该字段的最大值,然后需要过滤该值的数组内容。所以基本上是这样的:

db.collection.aggregate([
{“$match”:{
“RECNUM”:“1008”
}},
{“$REWIND”:“$prices”},
{“$组”:{
“\u id”:“$\u id”,
“RECUM”:{“$first”:“$RECNUM”},
“价格”:{“$push”:“$prices”},
“最长日期”:{
$max:“$prices.DATUM_VON”
}
}},
{“$REWIND”:“$prices”},
{“$project”:{
“RECNUM”:1,
"价格":一,,
“匹配”:{
“$eq”:[“$max_date”,“$prices.DATUM_VON”]
}
}},
{“$match”:{“matched”:true},
{“$组”:{
“\u id”:“$\u id”,
“RECNUM”:{“$first”:“$RECNUM”},
“价格”:{“$push”:“$prices”}
}}
])
只要阵列元素是唯一的,我们可以从MongoDB 2.6版和更高版本中获得更多的乐趣:

db.collection.aggregate([
{“$match”:{
“RECNUM”:“1008”
}},
{“$REWIND”:“$prices”},
{“$组”:{
“\u id”:“$\u id”,
“RECUM”:{“$first”:“$RECNUM”},
“价格”:{“$push”:“$prices”},
“最长日期”:{
$max:“$prices.DATUM_VON”
}
}},
{“$project”:{
“RECNUM”:1,
“价格”:{
“$setDifference”:[
“$map”:{
“输入”:“$prices”,
“as”:“p”,
“在”:{
“$cond”:[
{“$eq”:[“$$p.DATNUM_VON”,“$max_date”]},
“$$p”,
错误的
]
}
},
错误的
]
}
}}
])
看起来更丰满一些,但对于MongoDB 2.6和更高版本来说,这通常是一种更快的方法,尤其是对于更大的阵列


对于您实际输出可能需要的字段,都是用缩写符号表示的,但您应该了解一般情况。在对某些值进行分组时,
$first
运算符是您的朋友。

虽然已经提到您确实应该将此处的“日期”类型更改为实际的BSON日期而不是字符串,但至少它是一个“词法”字符串,因此对于比较是有效的

你真的想要比你最初的尝试更复杂一点的东西。关键是您需要在数组中找到该字段的最大值,然后需要过滤该值的数组内容。所以基本上是这样的:

db.collection.aggregate([
{“$match”:{
“RECNUM”:“1008”
}},
{“$REWIND”:“$prices”},
{“$组”:{
“\u id”:“$\u id”,
“RECUM”:{“$first”:“$RECNUM”},
“价格”:{“$push”:“$prices”},
“最长日期”:{
$max:“$prices.DATUM_VON”
}
}},
{“$REWIND”:“$prices”},
{“$project”:{
“RECNUM”:1,
"价格":一,,
“匹配”:{
“$eq”:[“$max_date”,“$prices.DATUM_VON”]
}
}},
{“$match”:{“matched”:true},
{“$组”:{
“\u id”:“$\u id”,
“RECNUM”:{“$first”:“$RECNUM”},
“价格”:{“$push”:“$prices”}
}}
])
只要阵列元素是唯一的,我们可以从MongoDB 2.6版和更高版本中获得更多的乐趣:

db.collection.aggregate([
{“$match”:{
“RECNUM”:“1008”
}},
{“$REWIND”:“$prices”},
{“$组”:{
“\u id”:“$\u id”,
“RECUM”:{“$first”:“$RECNUM”},
“价格”:{“$push”:“$prices”},
“最长日期”:{
$max:“$prices.DATUM_VON”
}
}},
{“$project”:{
“RECNUM”:1,
“价格”:{
“$setDifference”:[
“$map”:{
“输入”:“$prices”,
“as”:“p”,
“在”:{
“$cond”:[
{“$eq”:[“$$p.DATNUM_VON”,“$max_date”]},
“$$p”,
错误的
]
}
},
错误的
]
}
}}
])
看起来更丰满一些,但对于MongoDB 2.6和更高版本来说,这通常是一种更快的方法,尤其是对于更大的阵列


对于您实际输出可能需要的字段,都是用缩写符号表示的,但您应该了解一般情况。在对某些值进行分组时,
$first
运算符是您的朋友。

请注意类型。示例中的所有数据都存储为字符串,这可能导致某些操作无法按预期工作。如果可能的话,你应该使用ISODate()对象来表示日期。@Martin我同意一般的看法,但评论并没有真正解决问题,或者要求澄清问题。注意类型。示例中的所有数据都存储为字符串,这可能导致某些操作无法按预期工作。如果可能的话,你应该使用ISODate()对象来表示日期。@Martin我同意一般的看法,但评论并没有真正涉及到解决问题或请求解决问题