我认为你可以使用聚合管道实现你想要的两件事。
- 获取所有包含“wordAbc”和/或“wordXyz”的文章
selectedWord、preferredWord 或同义词
首先您需要填充words数组的details字段中的所有单词,然后匹配基于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 和同义词中的所有唯一词
数据库中的所有文章
在这种情况下,你将不得不unwindwords数组,然后populatewords.details来自words集合,然后unwindsynonyms数组,这样我们就可以创建一组@ 987654339@、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"]}
}
}])
第二次聚合的解释。
-
$project : 我们只想要单词,所以我保留了所有文章的单词字段,并从管道中删除了所有其他不必要的字段。
-
$unwind : 我们需要展开 words 数组,以便我们可以在管道的下一阶段从 words 集合中 $lookup words.details
-
$lookup :从单词集合中填充详细信息。
-
$unwind :由于 $lookup 返回一个数组,我们需要展开它以使其成为一个对象
-
$unwind : 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 使用的所有运算符的详细信息,请阅读相应的文档。
$setUnion documentation
$addToSet documentation
$project documentation
$unwind documentation
Documentation of all the operators of mongodb aggregation pipeline
希望对你有帮助