Javascript 是否更正Mongoose语法以查询user1存档的邮件?
这是查找user1收到的所有文档的正确查询吗?其中,对于user1,archive=trueJavascript 是否更正Mongoose语法以查询user1存档的邮件?,javascript,node.js,mongodb,mongoose,Javascript,Node.js,Mongodb,Mongoose,这是查找user1收到的所有文档的正确查询吗?其中,对于user1,archive=true var query = { "to.username": user1, "to.section.archive": true }; Models.Message.find( query ).sort([['to.updated','descending']]).exec(function (err, messages) { 消息架构的示例嵌入“To”数组如下所示: "
var query = {
"to.username": user1,
"to.section.archive": true
};
Models.Message.find( query ).sort([['to.updated','descending']]).exec(function (err, messages) {
消息架构的示例嵌入“To”数组如下所示:
"to" : [
{
"user" : ObjectId("53b96c735f4a3902008aa019"),
"username" : "user1",
"updated" : ISODate("2014-07-08T06:23:43.000Z"),
"_id" : ObjectId("53bb8e6f1e2e72fd04009dad"),
"section" : {
"in" : true,
"out" : false,
"archive" : true
}
}
]
查询应该只返回上面的文档(user1和archive为true)…而不是下一个文档(archive为true,但不是user1):
您希望操作符选择同时具有条件和投影操作符的元素:
Models.Message.find(
{
"to": {
"$elemMatch": {
"username": "user2",
"section.archive": true
}
}
},
{ "created": 1, "message": 1, "to.$": 1 }
).sort([['to.updated','descending']]).exec(function (err, messages) {
});
请注意,此仅在匹配投影的“第一”元素时起作用。此外,您还希望对匹配数组元素的值进行“排序”,而使用.find()
和.sort()
修饰符无法进行排序
如果希望数组中有多个匹配项,则需要使用聚合方法。这样做比其他方式更复杂的“过滤”和“投影”:
Models.Message.aggregate([
// Match documents
{ "$match": {
"to": {
"$elemMatch": {
"username": "user2",
"section.archive": true
}
}
}},
// Unwind to de-normalize
{ "$unwind": "$to" },
// Match the array elements
{ "$match": {
"to.username": "user2",
"to.section.archive": true
}},
// Group back to the original document
{ "$group": {
"_id": "$_id",
"created": { "$first": "$created" },
"message": { "$first": "$message" },
"to": { "$push": "$to" }
}}
// Sort the results "correctly"
{ "$sort": { "to.updated": -1 } }
],function(err,messages) {
});
或者,您可以通过在MongoDB 2.6或更高版本中对运算符应用一些逻辑来避免使用and。只需观察数组内容是否“真正”唯一,就像应用于生成的“过滤”数组一样:
甚至使用:
但在文档的所有级别上操作时要小心,这样您的结果可能会出乎意料
很可能您的“to”数组实际上只有一个匹配的条目,所以一般来说,标准投影应该可以。但以下是如何使用MongoDB在数组元素中进行“多次”匹配。您建议使用什么方法返回每个匹配文档的全部内容?在测试之后,我使用$unwind+$group AGGRAGRATION,所有其他字段都使用$first累计。在最佳实践中,这一排名如何?@StackThis刚刚注意到,您当然希望对匹配元素的“更新”日期进行“排序”。因此,您当然需要一个聚合方法来实现这一点。你正在做的很好,其他方法是新的介绍。如果要查找多个数组匹配项,您可能还需要在分组中投影一个
$min
或$max
日期值以进行排序。甚至可能在分组之前对这些匹配项进行排序。感谢您的更新。。当你的更新出现时,我正在研究聚合的$sort语法!很高兴看到所有的方法,非常感谢您的体贴和支持insight@StackThis最近还发布了一篇文章,其中显示了从数组中提取某些内容以进行排序。更复杂一点,但涵盖了一般原则,如果您有多个数组匹配,您需要决定排序的值。Thaks for the head up。。作品中有一个可以直接从中受益的特点。。仔细考虑一下,然后再仔细看看这篇文章。。最好的,
Models.Message.aggregate([
// Match documents
{ "$match": {
"to": {
"$elemMatch": {
"username": "user2",
"section.archive": true
}
}
}},
// Unwind to de-normalize
{ "$unwind": "$to" },
// Match the array elements
{ "$match": {
"to.username": "user2",
"to.section.archive": true
}},
// Group back to the original document
{ "$group": {
"_id": "$_id",
"created": { "$first": "$created" },
"message": { "$first": "$message" },
"to": { "$push": "$to" }
}}
// Sort the results "correctly"
{ "$sort": { "to.updated": -1 } }
],function(err,messages) {
});
Models.Message.aggregate([
{ "$match": {
"to": {
"$elemMatch": {
"username": "user2",
"section.archive": true
}
}
}},
{ "$project": {
"created": 1,
"message": 1,
"_id": 1,
"to": {
"$setDifference": [
{
"$map": {
"input": "$to",
"as": "el",
"in": {
"$cond": [
{
"$and": [
{ "$eq": [ "$$el.username", "user2" ] },
"$$el.section.archive"
]
},
"$$el",
false
]
}
}
},
[false]
]
}
}},
{ "$sort": { "to.updated": -1 } }
],function(err,messages) {
});
Models.Messages.aggregate([
{ "$match": {
"to": {
"$elemMatch": {
"username": "user2",
"section.archive": true
}
}
}},
{ "$redact": {
"$cond": {
"if": {
"$and": [
{ "$eq": [
{ "$ifNull": [ "$username", "user2" ] },
"user2"
] },
{ "$ifNull": [ "$section.archive", true ] }
]
},
"then": "$$DESCEND",
"else": "$$PRUNE"
}
}},
{ "$sort": { "to.updated": -1 } }
],function(err,messages) {
});