流星:如何按数组的第一项对文档进行排序

Meteor: How to sort documents by the first item of an array

本文关键字:一项 文档 排序 何按 数组 流星      更新时间:2023-09-26

研究论文应按作者姓氏排序。这是一个作者的JSON的样子:

{
    "_id" : "ADnijjRpoWkTEGgkc",
    "authors" : [ 
        {
            "lastName" : "Rahbaran",
            "firstName" : "Amir"
        }
    ],
    "title" : "Bricolage revisted",
    "outlet" : "Journal of Strategic Management",
    "year" : "2017",
    "abstract" : "dicta sunt explicabo. Nemo enim ..."
}

如果只存储了一个作者,则相应的模板帮助程序可以完美运行:

return Publications.find({}, {
      sort: {"authors.lastName": -1}
    }).fetch(); 

问题:在许多情况下,一篇研究论文有多个作者:

这将是 JSON:

{
    "_id" : ObjectId("56b06047204a563ca4207e8e"),
    "authors" : [ 
        {
            "lastName" : "Lennon",
            "firstName" : "John"
        }, 
        {
            "lastName" : "McCartney",
            "firstName" : "Paul"
        }
    ],
    "title" : "The Beatles - revisted",
    "outlet" : "Journal of Great Music",
    "year" : "1968",
    "abstract" : "Ob-La-Di, Ob-La-Da ... "
}

现在,我尝试sort: {"authors.lastName.0": -1}sort: {"authors.lastName[0]": -1}无济于事。

我提出了map,reduce和聚合的概念,但不知道如何在这里应用以及是否有必要。

或者也许流星有包装或"技巧"?

任何帮助真的非常感谢。

假设您始终至少有一个作者,则可以执行以下操作:

Publications.find({}, {
  sort: {
    'authors.0.lastName': -1
  }
});
db.publications.find({}).sort({"authors.lastName":-1})

工作得很好。它首先对文档中authors数组进行排序,选取第一个元素,然后对文档进行排序。文档。

另一种通过aggregate()方法使用聚合框架的替代方法,您可以对作者数组和文档进行排序。虽然 meteor 还不支持aggregate(),但您需要安装聚合框架包 - 它没有任何花哨的作用,只是为您包装了一些 Mongo 方法。

只要流星加meteorhacks:aggregate,你应该做生意。这将为流星添加适当的聚合支持。

现在,您需要运行此管道才能获得所需的结果:

var pipeline = [
    { "$unwind": "authors" },
    { "$sort": { "authors.lastName": -1 } },
    {
        "$group": {
            "_id": "$authors",
            "authors": { "$push": "$authors" },
            "title": { "$first": "$title" },
            "outlet": { "$first": "$outlet" },
            "year": { "$first": "$year" },
            "abstract": { "$first": "$abstract" }
        }
    },
    { "$sort": { "authors.lastName": -1 } },
];
return Publications.aggregate(pipeline);