在 Mongoose 中对子文档进行排序
Posted
技术标签:
【中文标题】在 Mongoose 中对子文档进行排序【英文标题】:Sorting a Subdocument in Mongoose 【发布时间】:2016-09-18 08:03:42 【问题描述】:我正在尝试按日期对 Mongoose 的输出进行排序,该日期存储在子文档中。我相信这可以在客户端更轻松地完成,但我想限制对服务器资源的消耗并延迟加载子文档,而不是一次加载它们。
我正在开发私人消息功能。我定义了一个名为 Conversations 的架构,并且定义了另一个名为 messages 的架构。他们的代码如下:
const mongoose = require('mongoose');
const ChatSchema = new mongoose.Schema(
messageBody:
type: String,
required: true
,
from:
type: String,
required: true
,
timestamps: true // Saves createdAt and updatedAt as dates. createdAt will be our timestamp.
);
const ConversationSchema = new mongoose.Schema(
participants: [String],
messages: [ChatSchema]
);
module.exports = mongoose.model('Chat', ChatSchema);
module.exports = mongoose.model('Conversation', ConversationSchema);
消息保存得很好,信息似乎正确存储在数据库中。当我尝试使用 cursor.sort() 方法首先返回最新消息时,我的问题就出现了。查询(要遵循的代码)按预期返回一条消息,但我无法让它返回最新消息。
exports.getConversations = function(req, res, next)
// Only return one message from each conversation to display as snippet
Conversation.find( participants: req.user._id )
.sort('-messages.createdAt')
.slice('messages', 1).exec(function(err, conversations)
if (err)
res.send( error: err );
return next(err);
// other code...
我已经尝试了我在这篇文章中找到的所有类型的变体,但无济于事:https://***.com/a/15081087/5956144
【问题讨论】:
【参考方案1】:您无需与 ORM(一个缓慢且记录不充分的 ORM)搏斗,即可通过嵌套属性对对象数组进行排序。穿上你的超棒裤子,推出你自己的排序功能,然后收工。
function byMessageCreatedAt(a, b)
//modify the below comparison however you need to to compare two times
return a.messages.createdAt - b.messages.createdAt
var results = conversation.find(blah).sort(byMessageCreatedAt);
找到了here在javascript中排序的详细信息
【讨论】:
我试图避免的一件事是为每个对话请求所有消息的开销。如果对话中有数百或数千条消息,并且每次用户访问他们的收件箱时都会被拉出,那将是非常低效的,对吗?也许我错了。似乎应该有更好的方法来做如此微不足道的事情。从那以后我就尝试过聚合。这些让我很接近,但也没有让我一直走到那里,因为我无法使用 .find() 或 .select() 过滤结果。 明确一点:通过 mongoose 提供的语法进行排序只是语法糖。无论您使用哪种排序方法,您每次仍然在对结果集进行排序。您的评论与您的原始评论完全不同。您最初的问题是“如何对查询结果进行排序”。现在你在问“我如何限制结果集”。以上是关于在 Mongoose 中对子文档进行排序的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Mongoose ORM 选择不使用常规的 mongo 语法进行查找、排序等?