简体   繁体   English

MongoDB按其他文档中的属性排序

[英]MongoDB sort by property in other document

In order to expand the JSON-API capabilities of my node.js application, I'm trying to sort a query based on relationships (AKA other documents), although I don't want to return them. 为了扩展我的node.js应用程序的JSON-API功能,尽管我不想返回它们,但我试图基于关系(又称为其他文档)对查询进行排序。

According to the JSON-API documentation : 根据JSON-API文档

a sort field of author.name could be used to request that the primary data be sorted based upon the name attribute of the author relationship. author.name的排序字段可用于请求根据author关系的name属性对主要数据进行排序。

Eg db.collection('books').find({}) returns: 例如db.collection('books').find({})返回:

[
    {
        type: "book",
        id: "2349",
        attributes: {
            title: "My Sweet Book"
        },
        relationships: {
            author: {
                data: {
                    type: "authors",
                    id: "9"
                }
            }
        }
    },
    {} // etc ...
]

db.collection('authors').find({id: "9"}) returns: db.collection('authors').find({id: "9"})返回:

[
    {
        type: "author",
        id: "9",
        attributes: {
            name: "Hank Moody"
        }
    }
]

Now I need some way to do something similar to eg: 现在,我需要某种方式来做类似的事情:
db.collection('books').find({}).sort({"author.name": -1})

I think I need to convert the query to an aggregation so I can use the $lookup operator, but I'm not sure how to use localField and foreignField . 我想我需要将查询转换为聚合,以便可以使用$lookup运算符,但是我不确定如何使用localFieldforeignField

db.collection('books').aggregate([
    {$match: {}},
    {$lookup: {from: "authors", localField: "attributes.author.data.id", foreignField: "id", as: "temp.author"}},
    {$sort: {"$books.temp.author.name": -1}},
    {$project: {temp: false}},
])

Notes 笔记

  • This will be a global function for fetching JSON-API data. 这将是用于获取JSON-API数据的全局函数。
    • This means we don't know wether a sort key is an attribute or a relationship . 这意味着我们不知道排序键是attribute还是relationship
  • Most servers run LTS versions and have MongoDB 3.2 大多数服务器运行LTS版本并具有MongoDB 3.2

You can try below aggregation. 您可以尝试以下汇总。

$lookup to join to authors collection followed by $unwind to flatten the book_author array for applying $sort on name field and $project with exclusion to remove book_author field ( only works starting Mongo 3.4 version ). $lookup加入authors集合,然后$unwind放平book_author数组,以便在$sort name字段上应用$sort ,并在$project以排除book_author字段(仅从Mongo 3.4版本开始有效)。 For lower versions you have to include all the other fields you want to keep and excluding book_author field in the $project stage. 对于较低版本,必须在$project阶段中包括要保留的所有其他字段,并排除book_author字段。

 db.collection('books').aggregate([{
    $lookup: {
        from: "authors",
        localField: "relationships.author.data.id",
        foreignField: "id",
        as: "book_author"
    }
 }, {
    $unwind: "$book_author"
 }, {
    $sort: {
        "book_author.attributes.name": -1
    }
 }, {
    $project: {
        "book_author": 0
    }
 }])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM