如何在MongoDB中執行等效的SQL Join?

如何在MongoDB中執行等效的SQL Join? 前端

例如,說您有兩個集合(用戶和評論),我想提取全部pid = 444的評論以及每一個用戶的用戶信息。 mongodb

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,獲取用戶對象,並將它們與註釋結果合併。 好像我作錯了。 服務器


#1樓

playORM可使用S-SQL(可伸縮SQL)爲您完成此操做,該SQL僅添加分區,以便您能夠在分區內進行聯接。 post


#2樓

您能夠運行SQL查詢,包括使用Postgres的mongo_fdw在MongoDB上進行聯接性能


#3樓

這取決於您要執行的操做。 大數據

當前,您已將其設置爲規範化數據庫,這很好,而且您的操做方式也很合適。 ui

可是,還有其餘方法能夠作到這一點。 spa

您可能有一個posts集合,其中包含每一個帖子的註釋以及對您能夠迭代查詢獲得的用戶的引用。 您能夠將用戶名和註釋一塊兒存儲,也能夠將它們所有存儲在一個文檔中。 設計

NoSQL的優勢是它專爲靈活的模式和很是快速的讀寫而設計。 在典型的大數據場中,數據庫是最大的瓶頸,與應用程序和前端服務器相比,數據庫引擎更少……它們更昂貴,但功能更強大,硬盤空間也相對便宜。 標準化來自於試圖節省空間的概念,可是它伴隨着使數據庫執行復雜的聯接,驗證關係的完整性,執行級聯操做的成本。 若是開發人員正確地設計了數據庫,全部這些都使開發人員免於頭痛。

使用NoSQL,若是您接受冗餘和存儲空間不是由於它們的成本而引發的問題(執行更新所需的處理器時間和存儲額外數據的硬盤驅動器成本),那麼非規範化就不是問題了(對於嵌入式陣列而言成千上萬的項目多是性能問題,但大多數狀況下這不是問題)。 此外,您將爲每一個數據庫集羣提供多個應用程序和前端服務器。 讓他們承擔繁重的鏈接工做,讓數據庫服務器堅持讀寫。

TL; DR:您在作什麼很好,還有其餘方法能夠作到。 查看mongodb文檔的數據模型模式以獲取一些出色的示例。 http://docs.mongodb.org/manual/data-modeling/


#4樓

使用mongodb客戶端控制檯,咱們只需幾行就能夠經過簡單的功能將一個集合中的全部數據合併/合併,如今咱們能夠執行所需的查詢了。 下面是一個完整的示例,

.-做者:

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" : [ ]
}

我但願這條線能夠幫助您。


#5樓

您必須按照描述的方式進行操做。 MongoDB是非關係數據庫,不支持聯接。

相關文章
相關標籤/搜索