mongodb指南(翻譯)(十四) – developer zone – 資料類型和約定(三)之資料庫引用

來源:互聯網
上載者:User

由於mongodb是非關係型的(沒有串連(join)),文檔間的引用(“外鍵”)通常是在用戶端通過向伺服器進行額外查詢來解決的(linking)。

這些串連總是在用戶端解決的。直接/手動做這些是非常容易並且也是推薦這樣做的。

這裡還有一個很多驅動都支援的DBRef機制,它在一定程度上抽象了linking的概念。推薦的方法是使用直接/手動link

內嵌對象是對linking的一種備選方案並且很多時候它非常合適和表現優秀。

簡單的直接/手動linking

通常,手動編寫link解決方案就可以很好工作並且也很簡單。我們儲存_id中的值到資料庫的其他文檔,稍後對它進行查詢。例如:

> // grab a random blog post:
> p = db.postings.findOne();
{
"_id" : ObjectId("4b866f08234ae01d21d89604"),
"author" : "jim",
"title" : "Brewing Methods"
}
> // get more info on author of post p. this is the "linking" step.
> a = db.users.findOne( { _id : p.author } )
{ "_id" : "jim", "email" : "jim@gmail.com" }
> // inverse: given an author, find all blog posts for the author
> db.postings.find( {author : a._id } )

DBRef

DBRef是一種建立文檔間引用的更加正式的規範。DBRefs(通常)除了對象id外還包含一個集合名稱。大多數開發人員只在文檔中的集合可以改變為其他的時候才使用DBRef。如果你引用的集合總是相同的,那麼上面描述的手動引用會更加高效。

DBRef是在同一個資料庫中一個文檔對另一個文檔的引用。一個資料庫引用是標準的內嵌(JSON/BSON)對象:我們定義的一種約定,不是一個特殊類型。通過使用標準方法來表現,驅動和資料架構可以添加助手方法按照標準方法來操作引用。

在某些驅動中DBRef有一個優點,允許可選的原子性的用戶端解引用。在很多情境中,你可以只是把_id儲存為引用,然後按照前面“簡單手動引用”章節所說進行解引用。

DBRef引用值的文法是:

{ $ref : <collname>, $id : <idvalue>[, $db : <dbname>] }

<collname>是被引用的集合名(沒有資料庫名),<idvalue>是引用對象的欄位_id的值。$db是可選的(目前大部分驅動還不支援)並且允許引用的文檔是其他資料庫的(由<dbname>指定)。

 

不同語言/驅動中的DBRef

C#

使用DBRef類。建構函式的參數是集合名和_id。然後你可以使用Database類中的FollowReference方法來擷取引用文檔。

C++

c++驅動尚沒有提供方法來自動遍曆DBRefs。當然你還是可以手動來完成的。

Java

java使用DBRef類支援DB引用。

Javascript(mongo shell)

例子:

> x = { name : 'Biology' }
{ "name" : "Biology" }
> db.courses.save(x)
> x
{ "name" : "Biology", "_id" : ObjectId("4b0552b0f0da7d1eb6f126a1") }
> stu = { name : 'Joe', classes : [ new DBRef('courses', x._id) ] }
// or we could write:
// stu = { name : 'Joe', classes : [ {$ref:'courses',$id:x._id} ] }
> db.students.save(stu)
> stu
{
"name" : "Joe",
"classes" : [
{
"$ref" : "courses",
"$id" : ObjectId("4b0552b0f0da7d1eb6f126a1")
}
],
"_id" : ObjectId("4b0552e4f0da7d1eb6f126a2")
}
> stu.classes[0]
{ "$ref" : "courses", "$id" : ObjectId("4b0552b0f0da7d1eb6f126a1") }
> stu.classes[0].fetch()
{ "_id" : ObjectId("4b0552b0f0da7d1eb6f126a1"), "name" : "Biology" }
>

Perl

perl驅動沒有提供方法自動遍曆DBRefs,但是有一個CPAN包:MongoDBx::AutoDeref.當然你還可以手動遍曆他們。

PHP

除了在資料庫層面(MongoDB::createDBRef和MongoDB::getDBRef)和集合層面(MongoCollection::createDBRef和MongoCollection::getDBRef)的建立和解引用方法外,PHP還提供了MongoDBRef類來支援DB引用。

Python

在python中使用bson.dbref.DBRef類來建立一個DB引用。你還可以使用Database執行個體中的dereference方法讓解引用變得更加容易。

Ruby

Ruby也使用DBRef類和DB執行個體中的dereference方法來支援DB引用。例如:

@db = Connection.new.db("blog")
@user = @db["users"].save({:name => "Smith"})
@post = @db["posts"].save({:title => "Hello World", :user_id => @user.id})
@ref = DBRef.new("users", @post.user_id)
assert_equal @user, @db.dereference(@ref)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.