【问题标题】:How can I sort array by a field inside a MongoDB document如何按 MongoDB 文档中的字段对数组进行排序
【发布时间】:2015-09-11 22:47:26
【问题描述】:

我有一个名为question的文档

var QuestionSchema = new Schema({
    title: {
        type: String,
        default: '',
        trim: true
    },
    body: {
        type: String,
        default: '',
        trim: true
    },
    user: {
        type: Schema.ObjectId,
        ref: 'User'
    },
    category: [],
    comments: [{
        body: {
            type: String,
            default: ''
        },
        root: {
            type: String,
            default: ''
        },
        user: {
            type: Schema.Types.ObjectId,
            ref: 'User'
        },
        createdAt: {
            type: Date,
            default: Date.now
        }
    }],
    tags: {
        type: [],
        get: getTags,
        set: setTags
    },
    image: {
        cdnUri: String,
        files: []
    },
    createdAt: {
        type: Date,
        default: Date.now
    }
});

因此,我需要按根字段对comments 进行排序,如下所示

我尝试在后端手动对comments 的数组进行排序并尝试使用聚合,但我无法对其进行排序。请帮忙。

【问题讨论】:

  • 您能否请edit 向我们展示您到目前为止所尝试的内容,就您提到的聚合管道而言,您能否包含预期输出的实际代码而不是嵌入链接,因为我们希望重现相同的问题并帮助您解决它。

标签: javascript mongodb mongoose mongodb-query


【解决方案1】:

假设Question 是您代码中的模型对象,并且您当然想从createdAt 中按“日期”对“cmets”进行排序,然后使用.aggregate(),您将使用以下代码:

Question.aggregate([
    // Ideally match the document you want
    { "$match": { "_id": docId } },

    // Unwind the array contents
    { "$unwind": "comments" },

    // Then sort on the array contents per document
    { "$sort": { "_id": 1, "comments.createdAt": 1 } },

    // Then group back the structure
    { "$group": {
        "_id": "$_id",
        "title": { "$first": "$title" },
        "body": { "$first": "$body" },
        "user": { "$first": "$user" },
        "comments": { "$push": "$comments" },
        "tags": { "$first": "$tags" },
        "image": { "$first": "$image" },
        "createdAt": { "$first": "$createdAt" }
    }}
],
function(err,results) {
    // do something with sorted results
});

但这确实是大材小用,因为您没有在文档之间“聚合”。只需使用 JavaScript 方法即可。如.sort()

Quesion.findOneById(docId,function(err,doc) {
    if (err) throw (err);
    var mydoc = doc.toObject();
    mydoc.questions = mydoc.questions.sort(function(a,b) {
        return a.createdAt > b.createdAt;
    });
   console.log( JSON.stringify( doc, undefined, 2 ) ); // Intented nicely
});

因此,虽然 MongoDB 确实有“工具”在服务器上执行此操作,但当您检索数据时,在客户端代码中执行此操作最有意义,除非您确实需要跨文档“聚合”。

但是现在已经给出了两个示例用法。

【讨论】:

  • +1 表示“在客户端执行”或至少在 Mongo 中不行。当您想要处理多个文档时,您应该使用聚合,例如获取您网站上的最后 100 个 cmets
  • @stephane-ruhlmann 是的,这就是重点,非常感谢您获得它。太多人认为“NoSQL”方式只是他们从“SQL 方式”中汲取的“坏习惯”的延伸。事实上,即使使用 RDBMS 确实适合(或不适合)他们的目的,这也不是他们“应该做的”方式。只是试图指出什么是正确的,正如你所说的“在客户中”似乎是这里是正确的情况。
  • 很好的总结,没有什么可补充的!
猜你喜欢
  • 1970-01-01
  • 2020-09-08
  • 1970-01-01
  • 2015-05-07
  • 2023-01-12
  • 1970-01-01
  • 2017-12-16
  • 2016-08-20
  • 1970-01-01
相关资源
最近更新 更多