繁体   English   中英

Mongodb查询参考文件

[英]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组结果,

  1. 获取所有在selectedWordpreferredWord同义词中具有'wordAbc'和/或'wordXyz'的文章
  2. 获取数据库中所有文章中selectedWordpreferredWord同义词中的所有唯一词

使用猫鼬执行查询的最佳/有效方式是什么?

对于第一个结果,我尝试了部分查询,但收到了CastError消息,

Article.find({})
.populate( 'words', null, { 'details': {$in: ['wordAbc', 'wordXyz']}} )
.exec(function(err, docs) {});

我认为使用聚合管道可以实现您想要的所有事情。

  1. 获取所有在selectedWord,preferredWord或同义词中具有“ wordAbc”和/或“ wordXyz”的文章

首先,您需要填充words数组的details字段中的所有words ,然后根据selectedWordpreferredWordsynonyms匹配文章。

可以这样实现:

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"}
    }
}])
  1. 获取数据库中所有文章中selectedWord,preferredWord和同义词中的所有唯一词

在这种情况下,您将必须unwind words数组,然后populate words.detailswords集合中获取详细信息,然后unwind synonyms数组,以便我们可以在所有articles创建一组selectedWordpreferredWordsynonyms ,然后最终形成一个整体聚合管道最后阶段中所有唯一单词的集合。

可以这样实现:

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"]}
    }
}])

第二次聚合的说明。

  1. $project :我们只需要单词,所以我继续所有文章的word字段,并从管道中删除了所有其他不必要的字段。
  2. $unwind :我们需要展开word数组,以便我们可以$ lookup words.details在管道的下一阶段收集单词
  3. $lookup :从单词集合中填充详细信息。
  4. $unwind :由于$lookup返回一个数组,我们需要对其进行展开以使其成为对象
  5. $unwind :展开words.details.synonyms ,以便我们可以将它们分组并在管道的下一阶段中创建唯一的单词数组,在此阶段,聚合管道中的各个文档将如下所示:

     { words : { selectedWord :"someword", details : { preferredWord : "otherword", synonym : "synonymword" } } } 
  6. $project :我们需要使对象结构扁平化。 在此阶段之后,管道中的单个文档将如下所示:

     { selectedWord :"someword", preferredWord : "otherword", synonym : "synonymword" } 
  7. $group :将所有selectedWord合并为一个数组, preferredWord合并为一个数组,并将同义词合并为一个数组,$ addToSet用于删除重复的对象

  8. $project :组合所有3个数组并创建一个唯一单词数组

有关mongoDB使用的所有运算符的详细信息,请阅读相应的文档。

$ setUnion文档

$ addToSet文档

$ project文件

$ unwind文档

mongodb聚合管道的所有运算符的文档

我希望这可以帮助你

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM