如何在数组中获取子文档元素的计数以及如何在MongoDB中更新子文档的键
例如,以下是存储在mongodb中的整个doc:
{
"CompanyCode" : "SNBN",
"EventCode" : "ET00008352",
"EventName" : "Sunburn Presents Avicii India Tour",
"TktDetail" : [
{
"Type" : "Category I",
"Qty" : {
"10-Dec" : {
"value" : 58
},
"11-Dec" : {
"value" : 83
},
"12-Dec" : {
"value" : 100
}
}
},
{
"Type" : "Category II",
"Qty" : {
"10-Dec" : {
"value" : 4
},
"11-Dec" : {
"value" : 7
},
"12-Dec" : {
"value" : 8
}
}
},
{
"Type" : "PRICE LEVEL 1",
"Qty" : {
"11-Dec" : {
"value" : 2
}
}
},
{
"Type" : "CatIV",
"Qty" : {
"18-Dec" : {
"value" : 20
}
}
}
],
"TransDate" : [
"10-Dec-2013",
"11-Dec-2013",
"12-Dec-2013",
],
"VenueCode" : "SNBN",
"VenueName" : "Sunburn",
"_id" : ObjectId("52452db273b92012c41ad612")
}
这里TktDetail是一个数组,里面有一个包含多个元素的Qty子目录,我想知道如何在每个索引的Qty内部计算元素数?
例如,TktDetail数组的第0个索引包含1个Qty子目录,其中元素计数为3,而第3个索引在Qty子目录中的元素数为1。
如果我想更新子文件密钥,比如,我想将数量从“10月12日”更新为“2013年12月10日”,那怎么可能?
提前致谢,尽快寻找答复..
答案 0 :(得分:0)
首先,您实际上是在询问两个问题,"如何计算Qty
下的项目?&#34 ; 和"如何更改名称?" 。虽然通常不相关,但我会将它们视为同样的事情。
您需要做的是更改您的架构,这样做我会允许您获取商品数量,我会鼓励您更改那些字段名称也是如此。具体来说,您需要这样的架构:
"TktDetail" : [
{
"Type" : "Category I",
"Qty" : [
{ "date": ISODate("2013-12-10T00:00:00.000Z") , "value" : 58 },
{ "date": ISODate("2013-12-11T00:00:00.000Z"), "value" : 83 },
{ "date": ISODate("2013-12-01T00:00:00.000Z"), "value" : 100 },
]
},
所有血腥细节都在my answer here的类似问题中。但问题基本上是,当你以你的方式使用子文档时,你破坏了对此进行任何有意义的查询操作的机会,为了得到每个元素你必须< / strong>指定到达那里的完整路径。
answer有更多细节,但情况是你真的想要一个数组。权衡取舍,更新起来有点困难,特别是考虑到你有嵌套数组,但它更容易添加,更多更容易查询。
此外,相关,请将您的日期更改为日期和不字符串。用于MongoDB内部比较的字符串不好。将它们设置为正确的BSON日期(注意我将它们剪切到一天的开始),您可以比较,查询范围并执行有用的操作。您的应用程序代码将很高兴,因为驱动程序将返回真实日期对象,而不是您必须操纵的东西&#34;两种方式&#34;。
所以曾经你已经阅读,理解并实施了这一点,直到计算:
db.collection.aggregate([
// Unwind the TktDetail array to de-normalize
{"$unwind": "$TktDetail"},
// Also Unwind the Qty array
{"$unwind": "$Qty" },
// Get some group information and count the entries
{"$group": {
"_id": {
"_id": "$_id,
"EventCode": "$EventCode",
"Type": "$TktDetail.Type"
},
"Qty": {"$sum": 1 }
}},
// Project nicely
{"$project": {
"_id": 0,
"EventCode": "$_id.EventCode",
"Type: "$_id.Type",
"Qty": 1,
}},
// Let's even sort it
{"$sort": { "EventCode": 1, "Qty" -1 }}
])
这样,我们就可以Qty
为每个EventCode
的{{1}}中的项目获得数 Type
Qty
最低。
当前架构 ,而无需在代码中加载和遍历每个文档。
所以有这种情况。现在,如果您想要忽略,只需更改子文档键名,那么您需要删除密钥和基础文档并替换使用新的密钥名称,使用更新:
db.collection.update(
{ EventCode: "ET00008352"},
{ $unset:{ "TktDetail.0.Qty.10-Dec": "" }}
)
db.collection.update(
{ EventCode: "ET00008352"},
{ $set:{ "TktDetail.0.Qty.10-Dec-2013": { value: 58 } }}
)
您需要为每个项目执行此操作。
因此,您要么计算出架构转换,要么以其他方式进行批次工作,以便更改密钥。对于我自己,我会正确,只做一次,所以我以后不会遇到下一个问题。