在mongoDB中执行联盟 [英] Perform union in mongoDB

查看:52
本文介绍了在mongoDB中执行联盟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道如何在MongoDB的聚合中执行某种联合.让我们将以下文档想象成一个集合(该结构是出于示例的目的):

I'm wondering how to perform a kind of union in an aggregate in MongoDB. Let's imaging the following document in a collection (the structure is for the sake of the example) :

{
  linkedIn: {
    people : [
    {
      name : 'Fred'
     },
     {
       name : 'Matilda'
     }
   ]
  },
  twitter: {
    people : [
    {
       name : 'Hanna'
    },
    {
       name : 'Walter'
    }
   ]
  }
 }

如何进行汇总以返回twitter和linkedIn中的人员联合?

How to make an aggregate that returns the union of the people in twitter and linkedIn ?

{
 { name :'Fred', source : 'LinkedIn'},
 { name :'Matilda', source : 'LinkedIn'},
 { name :'Hanna', source : 'Twitter'},
 { name :'Walter', source : 'Twitter'},
}

推荐答案

有两种方法可以使用

There are a couple of approaches to this that you can use the aggregate method for

db.collection.aggregate([
    // Assign an array of constants to each document
    { "$project": {
        "linkedIn": 1,
        "twitter": 1,
        "source": { "$cond": [1, ["linkedIn", "twitter"],0 ] }
    }},

    // Unwind the array
    { "$unwind": "$source" },

    // Conditionally push the fields based on the matching constant
    { "$group": { 
        "_id": "$_id",
        "data": { "$push": {
            "$cond": [
                { "$eq": [ "$source", "linkedIn" ] },
                { "source": "$source", "people": "$linkedIn.people" },
                { "source": "$source", "people": "$twitter.people" }
            ]
        }}
    }},

    // Unwind that array
    { "$unwind": "$data" },

    // Unwind the underlying people array
    { "$unwind": "$data.people" },

    // Project the required fields
    { "$project": {
        "_id": 0,
        "name": "$data.people.name",
        "source": "$data.source"
    }}
])

或者使用与MongoDB 2.6中的某些运算符不同的方法:

Or with a different approach using some operators from MongoDB 2.6:

db.people.aggregate([
    // Unwind the "linkedIn" people
    { "$unwind": "$linkedIn.people" },

    // Tag their source and re-group the array
    { "$group": {
        "_id": "$_id",
        "linkedIn": { "$push": {
            "name": "$linkedIn.people.name",
            "source": { "$literal": "linkedIn" }
        }},
        "twitter": { "$first": "$twitter" }
    }},

    // Unwind the "twitter" people
    { "$unwind": "$twitter.people" },

    // Tag their source and re-group the array
    { "$group": {
        "_id": "$_id",
        "linkedIn": { "$first": "$linkedIn" },
        "twitter": { "$push": {
            "name":  "$twitter.people.name",
            "source": { "$literal": "twitter" }
        }}
    }},

    // Merge the sets with "$setUnion"
    { "$project": {
        "data": { "$setUnion": [ "$twitter", "$linkedIn" ] }
    }},

    // Unwind the union array
    { "$unwind": "$data" },

    // Project the fields
    { "$project": {
        "_id": 0,
        "name": "$data.name",
        "source": "$data.source"
    }}
])

当然,如果您根本不在乎源是什么

And of course if you simply did not care what the source was:

db.collection.aggregate([
    // Union the two arrays
    { "$project": {
        "data": { "$setUnion": [
            "$linkedIn.people",
            "$twitter.people"
        ]}
    }},

    // Unwind the union array
    { "$unwind": "$data" },

    // Project the fields
    { "$project": {
        "_id": 0,
        "name": "$data.name",
    }}

])

这篇关于在mongoDB中执行联盟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆