[英]Mongodb query on reference document
我在猫鼬中定义了两个架构,如下所示:
型号:文章
var articleSchema = new mongoose.Schema({
sequenceId: String
title: String,
abstract: String,
authors: [String],
date: Date,
words: [{
selectedWord: String,
details: { type: Schema.Types.ObjectId, ref: 'Word' }
}],
otherTags: [String]
})
型号:字
var wordSchema = new mongoose.Schema({
preferredWord: String,
synonyms: [String],
category: String
})
现在,我尝试在以下情况下获得2组结果,
使用猫鼬执行查询的最佳/有效方式是什么?
对于第一个结果,我尝试了部分查询,但收到了CastError消息,
Article.find({})
.populate( 'words', null, { 'details': {$in: ['wordAbc', 'wordXyz']}} )
.exec(function(err, docs) {});
我认为使用聚合管道可以实现您想要的所有事情。
- 获取所有在selectedWord,preferredWord或同义词中具有“ wordAbc”和/或“ wordXyz”的文章
首先,您需要填充words
数组的details
字段中的所有words
,然后根据selectedWord
, preferredWord
或synonyms
匹配文章。
可以这样实现:
Article.aggregate([{
$unwind : {
path :"$words",
preserveNullAndEmptyArrays :true
}
},{
$lookup : {
from : "words",
localField : "words.details",
foreignField : "_id",
as : "words.details"
}
},{
$unwind : {
path : "$words.details",
preserveNullAndEmptyArrays : true
}
},{
$match : {
$or : [{
"words.selectedWord" : {$in: ['wordAbc', 'wordXyz']}
},{
"words.details.preferredWord" : {$in: ['wordAbc', 'wordXyz']}
},{
"words.details.synonyms" : {$in: ['wordAbc', 'wordXyz']}
}]
}
},{
$group : {
_id : "$_id",
title : {$first : "$title"},
abstract : {$first : "$abstract"},
authors : {$first : "$authors"},
date : {$first : "$date"},
words: {$push : "$words"},
otherTags: {$first : "$otherTags"}
}
}])
- 获取数据库中所有文章中selectedWord,preferredWord和同义词中的所有唯一词
在这种情况下,您将必须unwind
words
数组,然后populate
words.details
从words
集合中获取详细信息,然后unwind
synonyms
数组,以便我们可以在所有articles
创建一组selectedWord
, preferredWord
和synonyms
,然后最终形成一个整体聚合管道最后阶段中所有唯一单词的集合。
可以这样实现:
Article.aggregate([{
$project : {
words : "$words"
}
},{
$unwind : "$words"
},{
$lookup : {
from : "words",
localField : "words.details",
foreignField : "_id",
as : "words.details"
}
},{
$unwind : "$words.details"
},{
$unwind : "$words.details.synonyms"
},{
$project : {
selectedWord : "$words.selectedWord",
preferredWord : "$words.details.preferredWord",
synonyms : "$words.details.synonyms"
}
},{
$group : {
_id : "null",
selectedWord : {$addToSet :"$selectedWord"},
preferredWord : {$addToSet :"$preferredWord"},
synonyms : {$addToSet :"$synonyms"}
}
},{
$project : {
commonWords : {$setUnion : ["$selectedWord","$preferredWord","$synonys"]}
}
}])
第二次聚合的说明。
$project
:我们只需要单词,所以我继续所有文章的word字段,并从管道中删除了所有其他不必要的字段。 $unwind
:我们需要展开word数组,以便我们可以$ lookup words.details在管道的下一阶段收集单词 $lookup
:从单词集合中填充详细信息。 $unwind
:由于$lookup
返回一个数组,我们需要对其进行展开以使其成为对象 $unwind
:展开words.details.synonyms
,以便我们可以将它们分组并在管道的下一阶段中创建唯一的单词数组,在此阶段,聚合管道中的各个文档将如下所示:
{ words : { selectedWord :"someword", details : { preferredWord : "otherword", synonym : "synonymword" } } }
$project
:我们需要使对象结构扁平化。 在此阶段之后,管道中的单个文档将如下所示:
{ selectedWord :"someword", preferredWord : "otherword", synonym : "synonymword" }
$group
:将所有selectedWord
合并为一个数组, preferredWord
合并为一个数组,并将同义词合并为一个数组,$ addToSet用于删除重复的对象
$project
:组合所有3个数组并创建一个唯一单词数组
有关mongoDB使用的所有运算符的详细信息,请阅读相应的文档。
我希望这可以帮助你
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.