如何在MongoDB中执行SQL连接等价物?

如何在MongoDB中执行SQL连接等价物?,mongodb,join,Mongodb,Join,如何在MongoDB中执行SQL连接等价物 例如,假设您有两个集合(用户和注释),我希望提取pid=444的所有注释以及每个集合的用户信息 comments { uid:12345, pid:444, comment="blah" } { uid:12345, pid:888, comment="asdf" } { uid:99999, pid:444, comment="qwer" } users { uid:12345, name:"john" } { uid:9999

如何在MongoDB中执行SQL连接等价物

例如,假设您有两个集合(用户和注释),我希望提取pid=444的所有注释以及每个集合的用户信息

comments
  { uid:12345, pid:444, comment="blah" }
  { uid:12345, pid:888, comment="asdf" }
  { uid:99999, pid:444, comment="qwer" }

users
  { uid:12345, name:"john" }
  { uid:99999, name:"mia"  }
是否有一种方法可以一次提取具有特定字段(例如……find({pid:444}))的所有注释以及与每个注释相关联的用户信息


目前,我首先获取符合我的条件的注释,然后计算结果集中的所有uid,获取用户对象,并将它们与注释的结果合并。看来我做错了

你必须按照你描述的方式来做。MongoDB是一个非关系数据库,不支持连接

你必须按照你描述的方式来做。MongoDB是一个非关系数据库,不支持连接

很多驱动程序都支持一种称为DBRef的规范

DBRef是用于在文档之间创建引用的更正式的规范。DBREF(通常)包括集合名称和对象id。大多数开发人员仅在集合可以从一个文档更改到下一个文档时才使用DBREF。如果引用的集合始终相同,则上面概述的手动引用会更有效

摘自MongoDB文档:数据模型>数据模型参考>

有一种规范,很多驱动程序都支持这种规范,称为DBRef

DBRef是用于在文档之间创建引用的更正式的规范。DBREF(通常)包括集合名称和对象id。大多数开发人员仅在集合可以从一个文档更改到下一个文档时才使用DBREF。如果引用的集合始终相同,则上面概述的手动引用会更有效

摘自MongoDB文档:数据模型>数据模型参考>

mongodb官方网站上的这一页正好解决了这个问题:

当我们显示故事列表时,我们需要显示发布故事的用户的姓名。如果我们使用关系数据库,我们可以对用户和存储执行连接,并在单个查询中获取所有对象。但MongoDB不支持连接,因此有时需要一些非规范化。这里,这意味着缓存“username”属性

关系纯粹主义者可能已经感到不安,好像我们违反了一些普遍规律。但我们要记住,MongoDB集合并不等同于关系表;每一个都有一个独特的设计目标。规范化表提供了一个原子的、孤立的数据块。然而,文档更接近于作为一个整体来表示对象。在社交新闻网站的案例中,可以认为用户名是发布故事的固有属性


mongodb官方网站上的这个页面正好解决了这个问题:

当我们显示故事列表时,我们需要显示发布故事的用户的姓名。如果我们使用关系数据库,我们可以对用户和存储执行连接,并在单个查询中获取所有对象。但MongoDB不支持连接,因此有时需要一些非规范化。这里,这意味着缓存“username”属性

关系纯粹主义者可能已经感到不安,好像我们违反了一些普遍规律。但我们要记住,MongoDB集合并不等同于关系表;每一个都有一个独特的设计目标。规范化表提供了一个原子的、孤立的数据块。然而,文档更接近于作为一个整体来表示对象。在社交新闻网站的案例中,可以认为用户名是发布故事的固有属性

下面是一个“加入”*演员电影收藏的示例:

它使用
.mapReduce()
方法

*加入-加入面向文档的数据库的替代方案

以下是一个“加入”*演员电影收藏的示例:

它使用
.mapReduce()
方法


*join-加入面向文档的数据库的一种替代方法

playORM可以使用S-SQL(可扩展SQL)为您完成这项工作,S-SQL只添加分区,这样您就可以在分区内进行连接。

playORM可以使用S-SQL(可扩展SQL)为您完成这项工作它只是添加了分区,这样您就可以在分区内执行联接。

您可以使用from Postgres在MongoDB上运行SQL查询,包括join。

您可以使用from Postgres在MongoDB上运行SQL查询,包括join。

这取决于您尝试执行的操作

您目前已将其设置为一个规范化数据库,这很好,而且您所采用的方式也很合适

然而,还有其他方法可以做到这一点

您可以有一个posts集合,该集合为每个post嵌入了注释,其中包含对用户的引用,您可以通过迭代查询来获取这些用户。您可以将用户名与注释一起存储,也可以将它们全部存储在一个文档中


NoSQL的特点是它是为灵活的模式和非常快速的读写而设计的。在典型的大数据场中,数据库是最大的瓶颈,与应用程序和前端服务器相比,数据库引擎更少……它们更昂贵但功能更强大,而且硬盘空间相对来说也非常便宜。规范化源于试图节省空间的概念,但它带来的代价是让数据库执行复杂的连接、验证关系的完整性、执行级联操作。如果开发人员正确地设计数据库,所有这些都可以为他们节省一些麻烦

对于NoSQL,如果您接受冗余和存储空间不是问题,因为它们的成本(更新所需的处理器时间和硬盘驱动器成本)
db.authors.insert([
    {
        _id: 'a1',
        name: { first: 'orlando', last: 'becerra' },
        age: 27
    },
    {
        _id: 'a2',
        name: { first: 'mayra', last: 'sanchez' },
        age: 21
    }
]);
db.categories.insert([
    {
        _id: 'c1',
        name: 'sci-fi'
    },
    {
        _id: 'c2',
        name: 'romance'
    }
]);
db.books.insert([
    {
        _id: 'b1',
        name: 'Groovy Book',
        category: 'c1',
        authors: ['a1']
    },
    {
        _id: 'b2',
        name: 'Java Book',
        category: 'c2',
        authors: ['a1','a2']
    },
]);
db.lendings.insert([
    {
        _id: 'l1',
        book: 'b1',
        date: new Date('01/01/11'),
        lendingBy: 'jose'
    },
    {
        _id: 'l2',
        book: 'b1',
        date: new Date('02/02/12'),
        lendingBy: 'maria'
    }
]);
db.books.find().forEach(
    function (newBook) {
        newBook.category = db.categories.findOne( { "_id": newBook.category } );
        newBook.lendings = db.lendings.find( { "book": newBook._id  } ).toArray();
        newBook.authors = db.authors.find( { "_id": { $in: newBook.authors }  } ).toArray();
        db.booksReloaded.insert(newBook);
    }
);
db.booksReloaded.find().pretty()
{
    "_id" : "b1",
    "name" : "Groovy Book",
    "category" : {
        "_id" : "c1",
        "name" : "sci-fi"
    },
    "authors" : [
        {
            "_id" : "a1",
            "name" : {
                "first" : "orlando",
                "last" : "becerra"
            },
            "age" : 27
        }
    ],
    "lendings" : [
        {
            "_id" : "l1",
            "book" : "b1",
            "date" : ISODate("2011-01-01T00:00:00Z"),
            "lendingBy" : "jose"
        },
        {
            "_id" : "l2",
            "book" : "b1",
            "date" : ISODate("2012-02-02T00:00:00Z"),
            "lendingBy" : "maria"
        }
    ]
}
{
    "_id" : "b2",
    "name" : "Java Book",
    "category" : {
        "_id" : "c2",
        "name" : "romance"
    },
    "authors" : [
        {
            "_id" : "a1",
            "name" : {
                "first" : "orlando",
                "last" : "becerra"
            },
            "age" : 27
        },
        {
            "_id" : "a2",
            "name" : {
                "first" : "mayra",
                "last" : "sanchez"
            },
            "age" : 21
        }
    ],
    "lendings" : [ ]
}
`db.commentss.insert([
  { uid:12345, pid:444, comment:"blah" },
  { uid:12345, pid:888, comment:"asdf" },
  { uid:99999, pid:444, comment:"qwer" }])`
db.userss.insert([
  { uid:12345, name:"john" },
  { uid:99999, name:"mia"  }])
`db.commentss.find().forEach(
    function (newComments) {
        newComments.userss = db.userss.find( { "uid": newComments.uid } ).toArray();
        db.newCommentUsers.insert(newComments);
    }
);`
db.newCommentUsers.find().pretty()
`{
    "_id" : ObjectId("5511236e29709afa03f226ef"),
    "uid" : 12345,
    "pid" : 444,
    "comment" : "blah",
    "userss" : [
        {
            "_id" : ObjectId("5511238129709afa03f226f2"),
            "uid" : 12345,
            "name" : "john"
        }
    ]
}
{
    "_id" : ObjectId("5511236e29709afa03f226f0"),
    "uid" : 12345,
    "pid" : 888,
    "comment" : "asdf",
    "userss" : [
        {
            "_id" : ObjectId("5511238129709afa03f226f2"),
            "uid" : 12345,
            "name" : "john"
        }
    ]
}
{
    "_id" : ObjectId("5511236e29709afa03f226f1"),
    "uid" : 99999,
    "pid" : 444,
    "comment" : "qwer",
    "userss" : [
        {
            "_id" : ObjectId("5511238129709afa03f226f3"),
            "uid" : 99999,
            "name" : "mia"
        }
    ]
}`
var Join = require('mongo-join').Join, mongodb = require('mongodb'), Db = mongodb.Db, Server = mongodb.Server;
db.open(function (err, Database) {
    Database.collection('Appoint', function (err, Appoints) {

        /* we can put conditions just on the top level */
        Appoints.find({_id_Doctor: id_doctor ,full_date :{ $gte: start_date },
            full_date :{ $lte: end_date }}, function (err, cursor) {
            var join = new Join(Database).on({
                field: '_id_Doctor', // <- field in Appoints document
                to: '_id',         // <- field in User doc. treated as ObjectID automatically.
                from: 'User'  // <- collection name for User doc
            }).on({
                field: '_id_Patient', // <- field in Appoints doc
                to: '_id',         // <- field in User doc. treated as ObjectID automatically.
                from: 'User'  // <- collection name for User doc
            })
            join.toArray(cursor, function (err, joinedDocs) {

                /* do what ever you want here */
                /* you can fetch the table and apply your own conditions */
                .....
                .....
                .....


                resp.status(200);
                resp.json({
                    "status": 200,
                    "message": "success",
                    "Appoints_Range": joinedDocs,


                });
                return resp;


            });

    });
db.users.find().forEach(
function (object) {
    var commonInBoth=db.comments.findOne({ "uid": object.uid} );
    if (commonInBoth != null) {
        printjson(commonInBoth) ;
        printjson(object) ;
    }else {
        // did not match so we don't care in this case
    }
});
1) Select from the collection you're interested in.
2) From that collection pull out ID's you need
3) Select from other collections
4) Decorate your original results.
 db.actors.insert( { actor: "Richard Gere", movies: ['Pretty Woman', 'Runaway Bride', 'Chicago'] });
 db.actors.insert( { actor: "Julia Roberts", movies: ['Pretty Woman', 'Runaway Bride', 'Erin Brockovich'] });
map = function() {
  for(var i in this.movies){
    key = { movie: this.movies[i] };
    value = { actors: [ this.actor ] };
    emit(key, value);
  }
}

reduce = function(key, values) {
  actor_list = { actors: [] };
  for(var i in values) {
    actor_list.actors = values[i].actors.concat(actor_list.actors);
  }
  return actor_list;
}
{ "_id" : { "movie" : "Chicago" }, "value" : { "actors" : [ "Richard Gere" ] } }
{ "_id" : { "movie" : "Erin Brockovich" }, "value" : { "actors" : [ "Julia Roberts" ] } }
{ "_id" : { "movie" : "Pretty Woman" }, "value" : { "actors" : [ "Richard Gere", "Julia Roberts" ] } }
{ "_id" : { "movie" : "Runaway Bride" }, "value" : { "actors" : [ "Richard Gere", "Julia Roberts" ] } }
{
   $lookup:
     {
       from: <collection to join>,
       localField: <field from the input documents>,
       foreignField: <field from the documents of the "from" collection>,
       as: <output array field>
     }
}
db.comments.aggregate({
    $lookup:{
        from:"users",
        localField:"uid",
        foreignField:"uid",
        as:"users_comments"
    }
})
db.users.aggregate({
    $lookup:{
        from:"comments",
        localField:"uid",
        foreignField:"uid",
        as:"users_comments"
    }
})
 db.getCollection('comments').aggregate([
        {$match : {pid : 444}},
        {$lookup: {from: "users",localField: "uid",foreignField: "uid",as: "userData"}},
   ])
SELECT S.* FROM LeftTable S
LEFT JOIN RightTable R ON S.ID = R.ID AND S.MID = R.MID  
WHERE R.TIM > 0 AND S.MOB IS NOT NULL
db.LeftTable.aggregate([
                        # connect all tables

                        {"$lookup": {
                          "from": "RightTable",
                          "localField": "ID",
                          "foreignField": "ID",
                          "as": "R"
                        }},
                        {"$unwind": "R"}
                   
                        ])
db.LeftTable.aggregate([
                        # connect all tables

                        {"$lookup": {
                          "from": "RightTable",
                          "localField": "ID",
                          "foreignField": "ID",
                          "as": "R"
                        }},
                        {"$unwind": "R"},

                        # define conditionals + variables

                        {"$project": {
                          "midEq": {"$eq": ["$MID", "$R.MID"]},
                          "ID": 1, "MOB": 1, "MID": 1
                        }}
                        ])
db.LeftTable.aggregate([
                        # connect all tables

                        {"$lookup": {
                          "from": "RightTable",
                          "localField": "ID",
                          "foreignField": "ID",
                          "as": "R"
                        }},
                        {"$unwind": "$R"},

                        # define conditionals + variables

                        {"$project": {
                          "midEq": {"$eq": ["$MID", "$R.MID"]},
                          "ID": 1, "MOB": 1, "MID": 1
                        }},

                        # join all conditionals

                        {"$match": {
                          "$and": [
                            {"R.TIM": {"$gt": 0}}, 
                            {"MOB": {"$exists": True}},
                            {"midEq": {"$eq": True}}
                        ]}},

                        # undefine conditionals

                        {"$project": {
                          "midEq": 0
                        }}

                        ])
{
   $lookup:
     {
       from: <collection to join>,
       localField: <field from the input documents>,
       foreignField: <field from the documents of the "from" collection>,
       as: <output array field>
     }
}
SELECT *, <output array field>
FROM collection
WHERE <output array field> IN (SELECT <documents as determined from the pipeline>
                               FROM <collection to join>
                               WHERE <pipeline> );