在 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 模式——对子文档使用对象而不是数组

为啥 Mongoose ORM 选择不使用常规的 mongo 语法进行查找、排序等?

使用 mongoose 对子子文档进行 CRUD

无法“跳过”猫鼬子文档

Mongoose - 无法在路径 notification.from 上使用排序填充,因为它是文档数组的子属性

如何从 mongoose 的 mongo 文档中返回一个数组?