我在猫鼬中定义了以下两个模式,
型号:文章
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]
})
型号:Word
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) {});
答案 0 :(得分:2)
我认为您可以使用聚合管道来实现您想要的所有事情。
- 获取所有包含“ wordAbc”和/或“ wordXyz”的文章 selectedWord,preferredWord或同义词
首先,您需要填充details
数组的words
字段中的所有单词,然后根据selectedWord
,preferredWord
或{{1}匹配文章}。
可以这样实现:
synonyms
- 获取selectedWord,preferredWord和同义词中的所有唯一单词 数据库中的所有文章
在这种情况下,您将必须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"}
}
}])
unwind
数组,然后words
集合中的populate
words.details
,然后words
{{ 1}}数组,以便我们可以在所有unwind
上创建synonyms
,selectedWord
和preferredWord
的集合,然后最终形成所有唯一的集合聚合管道最后阶段的单词。
可以这样实现:
synonyms
第二次汇总的说明。
articles
:我们只需要单词,所以我继续所有文章的单词字段,并从管道中删除了所有其他不必要的字段。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"]}
}
}])
:我们需要展开单词数组,以便我们可以在下一阶段的管道中$ lookup words.details来自单词收集的详细信息$project
:从单词收集中填充详细信息。$unwind
:由于$lookup
返回一个数组,我们需要对其进行展开以使其成为对象 $unwind
:展开$lookup
,以便我们可以将它们分组并在管道的下一阶段中创建唯一的单词数组,在这一阶段,聚合管道中的各个文档看起来像这个:
$unwind
words.details.synonyms
:我们需要使对象结构扁平化。在此阶段之后,管道中的单个文档将如下所示:
{
words : {
selectedWord :"someword",
details : {
preferredWord : "otherword",
synonym : "synonymword"
}
}
}
$project
:将所有{
selectedWord :"someword",
preferredWord : "otherword",
synonym : "synonymword"
}
组合成一个数组,$group
组合成一个数组,并将同义词组合成一个数组,$ addToSet用于删除重复的对象
selectedWord
:组合所有3个数组并创建一个唯一单词数组
有关mongoDB使用的所有运算符的详细信息,请阅读相应的文档。
Documentation of all the operators of mongodb aggregation pipeline
希望这对您有所帮助