多表查询
(创建时间:2012年08月24日 00:50:00)
Jangogo : 
MongoDB之DBref(关联插入,查询,删除) 实例深入

如图所示,A,B,C三个Collection互相关联。 其中的数字为document的value值。

关于DBref的入门可以看 javascript:lnkchk('8766166%2fsliated%2felcitra%2fgnaixijyzarc%2ften.ndsc.golb%2f%2f%3aptth'); 这篇文章。

我们先建立A collection。

  1. > var a={value:"1"}
  2. > var b={value:"2"}
  3. > var c={value:"9"}
  4. > var d={value:"10"}
  5. > db.A.save(a)
  6. > db.A.save(b)
  7. > db.A.save(c)
  8. > db.A.save(d)
  9. > db.A.find()
  10. { "_id" : ObjectId("4e3f33ab6266b5845052c02b"), "value" : "1" }
  11. { "_id" : ObjectId("4e3f33de6266b5845052c02c"), "value" : "2" }
  12. { "_id" : ObjectId("4e3f33e06266b5845052c02d"), "value" : "9" }
  13. { "_id" : ObjectId("4e3f33e26266b5845052c02e"), "value" : "10" }

B collection以A collection的 _id为ObjectId("4e3f33de6266b5845052c02c")作为Apid

所以:

  1. > var Ba={Apid:[new DBRef('A',ObjectId("4e3f33de6266b5845052c02c"))],value:3}
  2. > db.B.save(Ba)
  3. > var Ba={Apid:[new DBRef('A',ObjectId("4e3f33de6266b5845052c02c"))],value:4}
  4. > db.B.insert(Ba)
  5. > var Ba={Apid:[new DBRef('A',ObjectId("4e3f33de6266b5845052c02c"))],value:7}
  6. > db.B.insert(Ba)
  7. > var Ba={Apid:[new DBRef('A',ObjectId("4e3f33de6266b5845052c02c"))],value:8}
  8. > db.B.insert(Ba)
  9. > db.B.find()
  10. { "_id" : ObjectId("4e3f3dd96266b5845052c035"), "Apid" : [ { "$ref" : "A", "$id" : ObjectId("4e3f33de6266b5845052c02c") } ], "value" : 3 }
  11. { "_id" : ObjectId("4e3f3de16266b5845052c036"), "Apid" : [ { "$ref" : "A", "$id" : ObjectId("4e3f33de6266b5845052c02c") } ], "value" : 4 }
  12. { "_id" : ObjectId("4e3f3dec6266b5845052c037"), "Apid" : [ { "$ref" : "A", "$id" : ObjectId("4e3f33de6266b5845052c02c") } ], "value" : 7 }
  13. { "_id" : ObjectId("4e3f3df06266b5845052c038"), "Apid" : [ { "$ref" : "A", "$id" : ObjectId("4e3f33de6266b5845052c02c") } ], "value" : 8 }

C collection以B collection的 _id为 ObjectId("4e3f3de16266b5845052c036") 作为Apid

  1. > var Ca={Bpid:[new DBRef('B',ObjectId("4e3f3de16266b5845052c036"))],value:5}
  2. > db.C.save(Ca)
  3. > var Ca={Bpid:[new DBRef('B',ObjectId("4e3f3de16266b5845052c036"))],value:6}
  4. > db.C.save(Ca)
  5. > db.C.find()
  6. { "_id" : ObjectId("4e3f42f36266b5845052c03d"), "Bpid" : [ { "$ref" : "B", "$id" : ObjectId("4e3f3de16266b5845052c036") } ], "value" : 5 }
  7. { "_id" : ObjectId("4e3f42f96266b5845052c03e"), "Bpid" : [ { "$ref" : "B", "$id" : ObjectId("4e3f3de16266b5845052c036") } ], "value" : 6 }


目前为止3个collection 的关系已经建成。

查询


  1. <span style="font-size:16px;">> var a = db.B.findOne({"value":4})
  2. > a.Apid.forEach(function(ref){printjson(db[ref.$ref].findOne({"_id":ref.$id}));})
  3. { "_id" : ObjectId("4e3f33de6266b5845052c02c"), "value" : "2" }</span>

  1. > db.A.findOne({"_id":db.B.findOne().Apid[0].$id})
  2. { "_id" : ObjectId("4e3f33de6266b5845052c02c"), "value" : "2" }

其实好好想想引用不是必须的。

MongoDB 权威指南说了这么一句:

In short,the best time to use DBRefs are when you're storing heterogeneous references to documents in different collections.like when you want to take advantage of some additional DBRef-specific functionality in a driver or tool.



------------------------------------------------------******************------------------------------------------------------------

MongoDB Middle Level (关联多表查询)

DBRef is a more formal specification for creating references between documents. DBRefs (generally) include a collection name as well as an object id. Most developers only use DBRefs if the collection can change from one document to the next. If your referenced collection will always be the same, the manual references outlined above are more efficient.

  1. ^_^[root@:/usr/local/mongodb/bin]#./mongo
  2. MongoDB shell version: 1.8.2
  3. connecting to: test
  4. > var a = {name:"C++"}
  5. > db
  6. test
  7. > db.language.save(a)
  8. > db.language.find()
  9. { "_id" : ObjectId("4da32c897d2de864e0448e06"), "name" : "C++" }
  10. > var b = {name:"javascript"}
  11. > db.language.save(b)
  12. > db.language.find()
  13. { "_id" : ObjectId("4da32c897d2de864e0448e06"), "name" : "C++" }
  14. { "_id" : ObjectId("4da32cb17d2de864e0448e07"), "name" : "javascript" }
  15. > lan = {name:"obj1",computer:[new DBRef('language',a._id)]}
  16. {
  17. "name" : "obj1",
  18. "computer" : [
  19. {
  20. "$ref" : "language",
  21. "$id" : ObjectId("4da32c897d2de864e0448e06")
  22. }
  23. ]
  24. }
  25. > lan.computer[0]
  26. { "$ref" : "language", "$id" : ObjectId("4da32c897d2de864e0448e06") }
  27. > lan.computer[0].fetch()
  28. { "_id" : ObjectId("4da32c897d2de864e0448e06"), "name" : "C++" }
  29. > db.language.insert(lan)
  30. > db.language.find()
  31. { "_id" : ObjectId("4da32c897d2de864e0448e06"), "name" : "C++" }
  32. { "_id" : ObjectId("4da32cb17d2de864e0448e07"), "name" : "javascript" }
  33. { "_id" : ObjectId("4da33b487d2de864e0448e08"), "name" : "obj1", "computer" : [ { "$ref" : "language", "$id" : ObjectId("4da32c897d2de864e0448e06") } ] }
  34. > db.language.findOne({name:"obj1"}).computer[0].fetch()
  35. { "_id" : ObjectId("4da32c897d2de864e0448e06"), "name" : "C++" }
  36. > lan2 = {name:"obj2",computer:[new DBRef('language',b._id)]}
  37. {
  38. "name" : "obj2",
  39. "computer" : [
  40. {
  41. "$ref" : "language",
  42. "$id" : ObjectId("4da32cb17d2de864e0448e07")
  43. }
  44. ]
  45. }
  46. > db.language.insert(lan2)
  47. > db.language.find()
  48. { "_id" : ObjectId("4da32c897d2de864e0448e06"), "name" : "C++" }
  49. { "_id" : ObjectId("4da32cb17d2de864e0448e07"), "name" : "javascript" }
  50. { "_id" : ObjectId("4da33b487d2de864e0448e08"), "name" : "obj1", "computer" : [ { "$ref" : "language", "$id" : ObjectId("4da32c897d2de864e0448e06") } ] }


相关数据存放在一起,针对性的查询可以消除join,性能比分散存储要高且方便

文档中心