0

我正在学习Mongodb/Mongoose/Express,并且遇到了一个相当复杂的查询(相对于我当前的理解水平),我不确定如何最好地处理。我有一个集合 - 保持它的简单,让我们把它叫做实体 - 与嵌入式行动数组:Mongoose/Mongodb嵌入式文档中的前一个和下一个

name: String 
actions: [{ 
    name: String 
    date: Date 
}] 

我想什么做的是用含有最近一次的操作返回文档的数组(或最近到指定日期)和下一个操作(基于同一日期)。

这是可能的一个find()查询,还是我需要将其分解为多个查询并合并结果以生成一个结果数组?我正在寻找最有效的路线。

回答

0

只要你的“行动”是插入与列表中的最后一项“最近”,通常情况下,这是情况下,除非你是具体更新项目和更改日期,那么你真正想要做的是“项目”数组的最后一项。这就是$slice投影操作是:

Model.find({},{ "actions": { "$slice": -1 } },function(err,docs) { 
    // contains an array with the last item 
}); 

如果你确实是“更新”数组项和不断变化的日期,但你要查询最近的定期,那么你可能是最好关闭保持阵列的顺序。

Model.update(
    { 
     "_id": ObjectId("541f7bbb699e6dd5a7caf2d6"), 
    }, 
    { 
     "$push": { "actions": { "$each": [], "$sort": { "date": 1 } } } 
    }, 
    function(err,numAffected) { 

    } 
); 

这实际上更多的是,你可以用$sort修改做简单而不添加或删除现有的数组元素进行排序的:你可以用一些调节剂如做到这一点。在2.6之前的版本中,您还需要在此处使用$slice“更新”修饰符,但如果您实际上不想限制可能的大小,则可以将其设置为大于预期数组元素的值,但这可能一个好主意。

不幸的是,如果您通过$set语句“更新”,那么您不能在单个更新语句中“排序”,因为MongoDB不会同时允许对阵列执行这两种类型的操作。但是如果你能忍受这一点,那么这是一种保持数组排序的方式,因此第一个查询表单可以工作。

如果看起来太难以保留按日期排序的阵列,那么事实上您可以检索到我的意思是.aggregate()方法的最大值。这使得文件的更大的操作比可用于基本的查询,在一个多一点的成本:

Model.aggregate([ 
    // Unwind the array to de-normalize as documents 
    { "$unwind": "$actions" }, 

    // Sort the contents per document _id and inner date 
    { "$sort": { "_id": 1, "actions.date": 1 } }, 

    // Group back with the "last" element only 
    { "$group": { 
     "_id": "$_id", 
     "name": { "$last": "$name" }, 
     "actions": { "$last": "$actions" } 
    }} 
], 
function(err,docs) { 


}) 

并采用$unwind运算符,则进程,下一阶段,将“拉开”数组$sort的内容由“日期”。在$group流水线阶段,“_id”表示使用原始文档密钥“收集”,并且$last操作员从该分组边界上的“最后”文档中选择字段值(去归一化)。

所以你可以做很多事情,但最好的方法是保持你的数组有序,并使用基本的投影算子来简单地获取列表中的最后一项。

+0

终于回到这个项目。我想你可能误解了我(除非我只是没有看到这与我的问题有什么关系),因为你只是以每个文档的最大日期得到该操作。我要找的是根据日期检索下一个操作和上一个操作。因此,如果名称为“A”的实体的行为日期为1月1日,1月2日和1月4日,并且日期为1月3日,则我希望检索:{name:“A”,prev_action:{date:“ Jan 2nd“,...},next_action:{date:”Jan 4th“,...}} – jr1242 2015-03-09 00:06:12

+0

@jrwebdev Quote:”我想要做的是返回一个文档数组,每个文档包含最近的动作(或最近一次到指定日期)以及下一个动作(基于同一日期)。“所以你需要你的数组元素以某​​种方式顺序,这正是讨论的内容。 – 2015-03-09 00:09:39

相关问题