根据mongodb文档的长度对mongodb文档中的数组进行排序

时间:2017-05-23 17:13:14

标签: mongodb

我有一个像这样的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
    }
]}

在我的问题中,与以前的问题不同,数组名称不同,所以我不了解如何触发查询。

1 个答案:

答案 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目前不支持。

可能你应该考虑一下你是否真的为数据使用了适当的模式,因为看起来数组会更好用。