当前位置:  开发笔记 > 编程语言 > 正文

MongoDB中的$ unwind运算符是什么?

如何解决《MongoDB中的$unwind运算符是什么?》经验,为你挑选了3个好方法。

这是我与MongoDB的第一天,所以请跟我一起轻松:)

我无法理解$unwind操作员,也许是因为英语不是我的母语.

db.article.aggregate(
    { $project : {
        author : 1 ,
        title : 1 ,
        tags : 1
    }},
    { $unwind : "$tags" }
);

我想项目操作员是我能理解的(就像SELECT是,不是吗?).但是,$unwind(引用)为每个源文档中的展开数组的每个成员返回一个文档.

这是一个JOIN吗?如果是,如何的结果$project(有_id,author,titletags字段)可以用比较tags阵列?

注意:我从MongoDB网站上采用了这个例子,我不知道tags数组的结构.我认为这是一个简单的标签名称数组.



1> 小智..:

首先,欢迎来到MongoDB!

需要记住的是MongoDB采用"NoSQL"方法进行数据存储,因此会消除您心中的选择,联接等想法.它存储数据的方式是以文档和集合的形式,这允许动态方式从存储位置添加和获取数据.

话虽如此,为了理解$ unwind参数背后的概念,您首先必须了解您尝试引用的用例是什么.mongodb.org的示例文档如下:

{
 title : "this is my title" ,
 author : "bob" ,
 posted : new Date () ,
 pageViews : 5 ,
 tags : [ "fun" , "good" , "fun" ] ,
 comments : [
             { author :"joe" , text : "this is cool" } ,
             { author :"sam" , text : "this is bad" }
 ],
 other : { foo : 5 }
}

注意标签实际上是3个项目的数组,在这种情况下是"有趣","好"和"有趣".

$ unwind的作用是允许您为每个元素剥离文档并返回生成的文档.要以经典的方法来考虑这一点,它将是"对于tags数组中的每个项目,仅返回仅包含该项目的文档"的等效项.

因此,运行以下结果:

db.article.aggregate(
    { $project : {
        author : 1 ,
        title : 1 ,
        tags : 1
    }},
    { $unwind : "$tags" }
);

将返回以下文件:

{
     "result" : [
             {
                     "_id" : ObjectId("4e6e4ef557b77501a49233f6"),
                     "title" : "this is my title",
                     "author" : "bob",
                     "tags" : "fun"
             },
             {
                     "_id" : ObjectId("4e6e4ef557b77501a49233f6"),
                     "title" : "this is my title",
                     "author" : "bob",
                     "tags" : "good"
             },
             {
                     "_id" : ObjectId("4e6e4ef557b77501a49233f6"),
                     "title" : "this is my title",
                     "author" : "bob",
                     "tags" : "fun"
             }
     ],
     "OK" : 1
}

请注意,结果数组中唯一更改的内容是在tags值中返回的内容.如果您需要有关其工作方式的其他参考,我在此处添加了一个链接.希望这对您进入迄今为止遇到的最好的NoSQL系统之一有所帮助,并祝您好运.



2> JohnnyHK..:

$unwind 复制管道中的每个文档,每个数组元素一次.

因此,如果您的输入管道包含一个包含两个元素的文章doc tags,{$unwind: '$tags'}则会将管道转换为两个文章文档,除了tags字段之外是相同的.在第一个doc中,tags将包含原始doc的数组中的第一个元素,而在第二个doc中,tags将包含第二个元素.



3> xameeramir..:

让我们通过一个例子来理解它

这就是公司文档的样子:

原始文件

$unwind允许我们采取文档作为输入的是有一个数组值字段并产生输出文档,使得有一个为阵列中的每个元件一个输出文档.资源

$ unwind阶段

让我们回到我们公司的例子,看看展开阶段的使用.这个查询:


db.companies.aggregate([
    { $match: {"funding_rounds.investments.financial_org.permalink": "greylock" } },
    { $project: {
        _id: 0,
        name: 1,
        amount: "$funding_rounds.raised_amount",
        year: "$funding_rounds.funded_year"
    } }
])

生成包含金额和年份数组的文档.

项目产出

因为我们正在获得资金回合阵列中每个要素的筹集金额和资助年度.要解决这个问题,我们可以在此聚合管道中的项目阶段之前包含一个展开阶段,并通过说我们想要unwind资金回合数组来参数化:


db.companies.aggregate([
    { $match: {"funding_rounds.investments.financial_org.permalink": "greylock" } },
    { $unwind: "$funding_rounds" },
    { $project: {
        _id: 0,
        name: 1,
        amount: "$funding_rounds.raised_amount",
        year: "$funding_rounds.funded_year"
    } }
])

展开具有输出到下一阶段的文档的效果,而不是作为输入接收的文档

如果我们查看funding_rounds数组,我们知道每个数组funding_rounds都有一个raised_amount和一个funded_year字段.因此,unwind对于作为funding_rounds数组元素的每个文档,都会生成输出文档.现在,在这个例子中,我们的值是strings.但是,无论数组中元素的值类型如何,unwind都会为这些值中的每一个生成一个输出文档,这样所讨论的字段就只有该元素.在这种情况下funding_rounds,该元素将是这些文档中的一个,作为funding_rounds传递到我们project舞台的每个文档的值.结果,然后运行这个,现在我们得到一个amount和一个year.一个用于每一轮融资,每家公司我们收藏.这意味着我们的比赛产生了许多公司文件,而这些公司文件中的每一个都会产生许多文件.每个公司文件中的每个资金回合一个.unwind使用从match舞台传递给它的文件执行此操作.然后,每个公司的所有这些文件都会传递到project舞台上.

展开输出

因此,资助者是Greylock的所有文档(如查询示例中)将被分成许多文档,等于每个匹配过滤器的公司的资金轮数$match: {"funding_rounds.investments.financial_org.permalink": "greylock" }.然后每个结果文件将被传递给我们project.现在,unwind为它作为输入接收的每个文档生成一个精确的副本.所有字段都具有相同的键和值,但有一个例外,那就是funding_rounds字段而不是funding_rounds文档数组,而是具有单个文档的值,这是一个单独的资金回合.因此,拥有4轮融资的公司将unwind产生4个文件.除了funding_rounds字段之外,每个字段都是精确副本,而不是每个字段的数组,而是来自当前正在处理funding_rounds的公司文档的数组中的单个元素unwind.因此,unwind具有输出到下一阶段的文档比输入的文档更多的效果.这意味着我们的project舞台现在funding_rounds再次得到一个字段,不是一个数组,而是一个具有a raised_amount和a funded_year字段的嵌套文档.因此,project将为每个公司收到match过滤器的多个文档,因此可以单独处理每个文档,并为每个公司的每个资金轮次确定单独的金额和年份.


使用相同的文档会更好。
推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有