如何通过使用聚合添加mongoose中的值进行排序



我有两个模型,post和vote。

后模式

title:{
type: String,
required: true,
},
description:{
type: String,
required: true,
},
votes: [
{
type: Schema.Types.ObjectId,
ref: 'Vote'
}
],

投票模式

const voteSchema = new Schema({
post:{
type: Schema.Types.ObjectId,
ref: 'Post',
},
value:{
type: Number,
required: true,
},
});

我正试着按照最有价值的票数对帖子进行排序。

也许是这样的?

var posts = Post.aggregate([{$sort: { $group: votes: {$sum: value} }}

如有任何帮助,我们将不胜感激。

谢谢!

由于您正试图通过另一个集合的聚合数据$sort,因此需要首先使用$lookup才能从所有相关投票中获得总值:

let posts = await Post.aggregate([
{
$lookup: {
from: "votes",
let: { post_votes: "$votes" },
pipeline: [
{ $match: { $expr: { $in: [ "$_id", "$$post_votes" ] } } },
{ $group: { _id: null, total: { $sum: "$value" } }
],
as: "votesTotalValue"
}
},
{ $unwind: "$votesTotalValue" },
{ $sort: { "votesTotalValue.total": -1 } }
])

Mongo游乐场

灵感来自mongo网站上的这个例子。

db.sales.insertMany([
{ "_id" : 1, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("2"), "date" : ISODate("2014-03-01T08:00:00Z") },
{ "_id" : 2, "item" : "jkl", "price" : NumberDecimal("20"), "quantity" : NumberInt("1"), "date" : ISODate("2014-03-01T09:00:00Z") },
{ "_id" : 3, "item" : "xyz", "price" : NumberDecimal("5"), "quantity" : NumberInt( "10"), "date" : ISODate("2014-03-15T09:00:00Z") },
{ "_id" : 4, "item" : "xyz", "price" : NumberDecimal("5"), "quantity" :  NumberInt("20") , "date" : ISODate("2014-04-04T11:21:39.736Z") },
{ "_id" : 5, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("10") , "date" : ISODate("2014-04-04T21:23:13.331Z") },
{ "_id" : 6, "item" : "def", "price" : NumberDecimal("7.5"), "quantity": NumberInt("5" ) , "date" : ISODate("2015-06-04T05:08:13Z") },
{ "_id" : 7, "item" : "def", "price" : NumberDecimal("7.5"), "quantity": NumberInt("10") , "date" : ISODate("2015-09-10T08:43:00Z") },
{ "_id" : 8, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("5" ) , "date" : ISODate("2016-02-06T20:20:13Z") },
])

按项目数量分组,并根据数量对项目进行排序

db.sales.aggregate( [
{
$group: {
_id: "$item",
count: { $sum:"$quantity" }
}
}
],
{$sort:{"_id.quantity":1}} )

输出

{ 
"_id" : "jkl", 
"count" : NumberInt(1)
},
{ 
"_id" : "def", 
"count" : NumberInt(15)
},
{ 
"_id" : "abc", 
"count" : NumberInt(17)
},
{ 
"_id" : "xyz", 
"count" : NumberInt(30)
}

使用$lookup和排序从两个集合检索数据的代码示例

// data preparation, please use drop command in your work with caution      
original_id = ObjectId();     
db.post.insertOne({"_id":original_id,title:"hotel review"});
db.vote.insertOne({post_id:original_id, vote:22});
//
original_id = ObjectId();     
db.post.insertOne({"_id":original_id,title:"movie review"});
db.vote.insertOne({post_id:original_id, vote:99});
//
> db.post.find();
{ "_id" : ObjectId("5f42573349cf5c81666018f5"), "title" : "hotel review" }
{ "_id" : ObjectId("5f42581949cf5c81666018f7"), "title" : "movie review" }
> db.vote.find();
{ "_id" : ObjectId("5f42573349cf5c81666018f6"), "post_id" : ObjectId("5f42573349cf5c81666018f5"), "vote" : 22 }
{ "_id" : ObjectId("5f42581949cf5c81666018f8"), "post_id" : ObjectId("5f42581949cf5c81666018f7"), "vote" : 99 }
> db.post.aggregate([ {$lookup:     {from:"vote",      localField:"_id",      foreignField:"post_id",      as:"post_docs"            }     }, {$sort:{"post_docs.vote":-1}} ]).pretty();
{
"_id" : ObjectId("5f42581949cf5c81666018f7"),
"title" : "movie review",
"post_docs" : [
{
"_id" : ObjectId("5f42581949cf5c81666018f8"),
"post_id" : ObjectId("5f42581949cf5c81666018f7"),
"vote" : 99
}
]
}
{
"_id" : ObjectId("5f42573349cf5c81666018f5"),
"title" : "hotel review",
"post_docs" : [
{
"_id" : ObjectId("5f42573349cf5c81666018f6"),
"post_id" : ObjectId("5f42573349cf5c81666018f5"),
"vote" : 22
}
]
}
> db.post.aggregate([ {$lookup:     {from:"vote",      localField:"_id",      foreignField:"post_id",      as:"post_docs"            }     }, {$sort:{"post_docs.vote":1}} ]).pretty();
{
"_id" : ObjectId("5f42573349cf5c81666018f5"),
"title" : "hotel review",
"post_docs" : [
{
"_id" : ObjectId("5f42573349cf5c81666018f6"),
"post_id" : ObjectId("5f42573349cf5c81666018f5"),
"vote" : 22
}
]
}
{
"_id" : ObjectId("5f42581949cf5c81666018f7"),
"title" : "movie review",
"post_docs" : [
{
"_id" : ObjectId("5f42581949cf5c81666018f8"),
"post_id" : ObjectId("5f42581949cf5c81666018f7"),
"vote" : 99
}
]
}
>

最新更新