我有一个像这样的mongodb文件:
{
"_id" : 1,
"prdvalue" : 3600,
"[4,0:30,0]" : [
{
"h" : 21.0,
"l" : 30.0
}
],
"[10,0:24,55]" : [
{
"h" : 10.0,
"l" : 24.55
},
{
"h" : 10.0,
"l" : 24.55
},
{
"h" : 10.0,
"l" : 24.55
}
],
"[16,0:18,0]" : [
{
"h" : 16.0,
"l" : 18.0
},
{
"h" : 16.0,
"l" : 18.0
}
]}
现在,我想根据它们的长度按降序排列其中的数组,这样当我查询这个文档时,我必须得到如下所示的结果:
{
"_id" : 1,
"prdvalue" : 3600,
"[10,0:24,55]" : [
{
"h" : 10.0,
"l" : 24.55
},
{
"h" : 10.0,
"l" : 24.55
},
{
"h" : 10.0,
"l" : 24.55
}
],
"[16,0:18,0]" : [
{
"h" : 16.0,
"l" : 18.0
},
{
"h" : 16.0,
"l" : 18.0
}
],
"[4,0:30,0]" : [
{
"h" : 21.0,
"l" : 30.0
}
]}
在我的问题中,与以前的问题不同,数组名称不同,所以我不了解如何触发查询。
答案 0 :(得分:0)
根据JSON
spec:
对象是一组无序名称/值对。对象以{(左括号)开头,以}结尾(右大括号)。每个名称后跟:(冒号),名称/值对用(逗号)分隔。
然而,在release notes for MongoDB 2.6中它说:
MongoDB在写操作之后保留文档字段的顺序,但以下情况除外:
- _id字段始终是文档中的第一个字段。
- 包括重命名字段名称的更新可能会导致文档中字段的重新排序。
对于以前的版本,情况并非如此,因为MMAPv1
存储引擎使用填充因子为文档分配空间,如果文档上的update
超出该范围,则更新的字段将跳转到文档的末尾。有关详情,请参阅:MongoDB field order and document position change after update
然后,您可以使用mapReduce来实现您的目标:
db.sourceCollection.mapReduce(function () {
var obj = this;
var newObject = {};
Object
.keys(this)
.sort(function(a, b) {
return a.length - b.length;
})
.map(function(key) {
newObject[key] = obj[key];
});
emit(obj._id, newObject);
}, function(key, values) {
return values[0];
}, {
out: { inline: 1 }
}).results.map(function (doc) {
db.destinationCollection.insert(doc.value);
});
请记住,这只会对文档根目录中的字段进行排序,而不会对子文档中的字段进行排序。此外,由于实施细节,这是有效的,但根据ECMAScript
规范无法保证对象的属性顺序。
您可以改为使用Map,这会保留插入顺序:
Map对象按插入顺序迭代其元素 - for循环返回每个迭代的[key,value]数组。
但是,我认为MongoDB shell目前不支持。
可能你应该考虑一下你是否真的为数据使用了适当的模式,因为看起来数组会更好用。