【问题标题】:How to sort objects in a field by their value in MongoDB?如何按字段中的对象在 MongoDB 中的值对对象进行排序?
【发布时间】:2016-04-30 20:15:10
【问题描述】:

如果我有这样的文件

{
    "_id" : "word",
    "nextWords" : {
        "x" : 3,
        "y" : 2,
        "z" : 1,
        "h" : 1,
        "n" : 10
    }
}

我想返回按降序排序的“nextWords”中的对象。

我可以在 MongoDB Shell 或 Java 中执行此操作吗?

编辑:我希望“nextWords”根据其值按降序排序,因此预期输出为:

{
    "n" : 10
    "x" : 3,
    "y" : 2,
    "z" : 1,
    "h" : 1,
}

【问题讨论】:

  • { $push: { : { $each: [ , , ... ], $sort: } } }
  • 请您详细说明一下?我应该在哪里通过这个?如果是更新操作,我希望它适用于整个文档,我认为这很难写
  • 简而言之:你不能用这个数据模型。返回字段的顺序是任意的。您需要在代码中以编程方式进行排序。
  • 感谢您的评论,您认为我如何在 Java 的数据结构中返回“nextWords”,然后按其值对其进行排序?在这个模型中可行吗?
  • 您可以对数组进行排序,但不能对一组字段进行排序。他们没有秩序。

标签: mongodb mongodb-java


【解决方案1】:

JSON 对象没有顺序。来自the specs 第 4.3.3 节:

对象是对象类型的成员。它是一个无序的属性集合,每个属性 包含原始值、对象或函数。存储在对象属性中的函数称为 方法。

您不能依赖字段的顺序,这是无法保证的。

【讨论】:

    【解决方案2】:

    您可以改为按以下方式进行操作

    { "_id" : "word", "nextWords" : [ {"word" : "x","count" : 3 },.... ] }

    使用这个地图减少:

    String map = "function() { for(i in this.nextWords)emit(i.word,i.count) }
    
    String reduce = "function(key,value){return (value);}";
    

    在java中运行:

    MapReduceCommand cmd = new MapReduceCommand(collection, map, reduce, null, MapReduceCommand.OutputType.INLINE, null);
    
    MapReduceOutput out = collection.mapReduce(cmd);
    
    for (DBObject o : out.results()) {
           // here put them in an array 
        }
    

    //对数组进行排序

    【讨论】:

    • 发出值的顺序可能按顺序排列,也可能不按顺序排列。而你的 map reduce 并没有改变这个事实。此外,使用这种结构,完全不需要 map/reduce,因为 db.words.aggregate({$unwind:"$nextWords"},{$sort:{"$nextWord.count":-1}},{$group:{_id:"$word",sorted:{$push:"$nextWord"}}}) 会做同样的事情,再加上您放入代码中的迭代。
    • 我是这样写的,因为在 java 中使用 mongodb 的 api 使得访问嵌套的子文档变得很困难。 stackoverflow.com/questions/3985214/…
    • 您可以使用 Java 驱动程序进行聚合。 ;) 而且我怀疑您是否需要 m/r 才能访问子文档。
    猜你喜欢
    • 2021-01-08
    • 2012-12-24
    • 1970-01-01
    • 2017-05-01
    • 2011-05-16
    • 1970-01-01
    相关资源
    最近更新 更多