mongodb 關係、引用、覆蓋索引查詢

来源:http://www.cnblogs.com/orlion/archive/2016/02/16/5192251.html
-Advertisement-
Play Games

一、關係 MongoDB 的關係表示多個文檔之間在邏輯上的相互聯繫。文檔間可以通過嵌入和引用來建立聯繫。MongoDB 中的關係可以是:1對1,1對多,多對1,多對多。 一個用戶可以用多個地址,這是典型的一對多關係。 user文檔可以是: { "_id":ObjectId("52ffc33cd852


一、關係

  MongoDB 的關係表示多個文檔之間在邏輯上的相互聯繫。文檔間可以通過嵌入和引用來建立聯繫。MongoDB 中的關係可以是:1對1,1對多,多對1,多對多。

一個用戶可以用多個地址,這是典型的一對多關係。

  user文檔可以是:

{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "name": "Tom Hanks",
   "contact": "987654321",
   "dob": "01-01-1991"
}

  address文檔可以是:

{
   "_id":ObjectId("52ffc4a5d85242602e000000"),
   "building": "22 A, Indiana Apt",
   "pincode": 123456,
   "city": "Los Angeles",
   "state": "California"
} 

  1、嵌入式關係

  使用嵌入式方法,可以把地址文檔嵌入到用戶的文檔中

{
    "_id":ObjectId("52ffc33cd85242f436000001"),
   "contact": "987654321",
   "dob": "01-01-1991",
   "name": "Tom Benzamin",
   "address": [
      {
         "building": "22 A, Indiana Apt",
         "pincode": 123456,
         "city": "Los Angeles",
         "state": "California"
      },
      {
         "building": "170 A, Acropolis Apt",
         "pincode": 456789,
         "city": "Chicago",
         "state": "Illinois"
      }]
} 

  如果這樣保存的話可以這樣獲取用戶的地址:

db.users.findOne({"name":"Tom Benzamin"},{"address":1})

 

  這種數據結構的缺點是,如果用戶和用戶地址在不斷增加,數據量不斷變大,會影響讀寫性能。

 

  2、引用式方法

  這種方法類似於關係型資料庫中的外鍵,將address的_id存到user文檔中

  

{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "contact": "987654321",
   "dob": "01-01-1991",
   "name": "Tom Benzamin",
   "address_ids": [
      ObjectId("52ffc4a5d85242602e000000"),
      ObjectId("52ffc4a5d85242602e000001")
   ]
}

  我們可以讀取這些用戶地址的對象id(ObjectId)來獲取用戶的詳細地址信息。這種方法需要兩次查詢,第一次查詢用戶地址的對象id(ObjectId),第二次通過查詢的id獲取用戶的詳細地址信息。

  

var result = db.users.findOne({"name":"Tom Benzamin"},{"address_ids":1})
var addresses = db.address.find({"_id":{"$in":result["address_ids"]}})

 

二、資料庫引用

  mongodb的引用有兩種:手動引用(Manual References)與 DBRefs

  如果我們在不同的集合中 (address_home, address_office, address_mailing, 等)存儲不同的地址(住址,辦公室地址,郵件地址等)。這時候我們在調用不同地址時,也需要指定集合,一個文檔從多個集合引用文檔,我們應該使用 DBRefs。

  DBRef的形式:

{ $ref : , $id : , $db :  }

  其中$ref:集合名稱,$id:引用的id,$db:資料庫名稱(可選)。

  以下實例中用戶數據文檔使用了 DBRef, 欄位 address:

{
   "_id":ObjectId("53402597d852426020000002"),
   "address": {
   "$ref": "address_home",
   "$id": ObjectId("534009e4d852427820000002"),
   "$db": "w3cschoolcc"},
   "contact": "987654321",
   "dob": "01-01-1991",
   "name": "Tom Benzamin"
}

  address DBRef 欄位指定了引用的地址文檔是在 address_home 集合下的 w3cschoolcc 資料庫,id 為 534009e4d852427820000002。

  以下代碼中,我們通過指定 $ref 參數(address_home 集合)來查找集合中指定id的用戶地址信息:

var user = db.users.findOne({"name":"Tom Benzamin"})
var dbRef = user.address
db[dbRef.$ref].findOne({"_id":(dbRef.$id)})

  以上實例返回了 address_home 集合中的地址數據:

{
   "_id" : ObjectId("534009e4d852427820000002"),
   "building" : "22 A, Indiana Apt",
   "pincode" : 123456,
   "city" : "Los Angeles",
   "state" : "California"
}

 

三、覆蓋索引查詢

  覆蓋查詢是以下的查詢:

  • 所有的查詢欄位是索引的一部分
  • 所有的查詢返回欄位在同一個索引中

  

  由於所有出現在查詢中的欄位是索引的一部分, MongoDB 無需在整個數據文檔中檢索匹配查詢條件和返回使用相同索引的查詢結果。因為索引存在於RAM中,從索引中獲取數據比通過掃描文檔讀取數據要快得多。

  例:user集合:

{
   "_id": ObjectId("53402597d852426020000002"),
   "contact": "987654321",
   "dob": "01-01-1991",
   "gender": "M",
   "name": "Tom Benzamin",
   "user_name": "tombenzamin"
}

  創建聯合索引,欄位為gender和user_name

db.users.ensureIndex({gender:1,user_name:1})

  現在,該索引會覆蓋以下查詢:

db.users.find({gender:"M"},{user_name:1,_id:0})

  對於上述查詢,MongoDB的不會去資料庫文件中查找。相反,它會從索引中提取數據,這是非常快速的數據查詢。由於我們的索引中不包括 _id 欄位,_id在查詢中會預設返回,我們可以在MongoDB的查詢結果集中排除它。下麵的實例沒有排除_id,查詢就不會被覆蓋:

db.users.find({gender:"M"},{user_name:1})

  如果所有索引欄位是一個數組則不能使用覆蓋索引查詢,所有索引欄位是一個子文檔。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 今天用Xcode打包IPA文件給同事,結果提示import時,提示證書missing,找了半天沒發現問題,後來打開鑰匙串,發現證書全失效了!!!嚇死寶寶了~~~~(>_<)~~~~ 然後,處理它。 1.打開鑰匙串 2.進行如下圖操作,打開證書信息雙擊或右鍵均可 3.再次去打包,成功 註意:分享轉載請
  • Moshi 是一個現代化的JSON庫針對Android和Java。它可以很容易地解析JSON成Java對象: String json = ...; Moshi moshi = new Moshi.Builder().build(); JsonAdapter<BlackjackHand> jsonAd
  • 自定義視圖,視圖控制器,視圖控制器指定視圖,loadView,viewDidLoad,MVC,屏幕旋轉,記憶體警告
  • 迴圈廣告我們在開發中已經是熟得不能再熟了,今天整理這篇scrollview三屏復用廣告 原理使用scrollview里的三個imageview分別去載入不同的圖片,用少量的資源來顯示大量或不確定的廣告數量,不然如果用普通方法實現廣告,難道10個廣告用12個scrollview的contentsize
  • 如下圖是側滑的效果圖 實現的功能主要是用ViewDragHelper,用ViewDragHelper來自定義一個側滑面板來實現側滑 如下是自定義的側滑面板 1 package com.demo.sb.widget; 2 3 import com.nineoldandroids.view.ViewHe
  • 一:藍牙設備之間的通訊首要包含了四個進程 設置藍牙設備 尋覓區域網內也許或許匹配的設備 銜接設備 設備之間的數據傳輸 二:詳細編程完結 1. 發動藍牙功用 首要經過調用靜態辦法getDefaultAdapter()獲取藍牙適配器BluetoothAdapter,假如回來為空,則無法繼續執行了。例如安
  • 前言: QQ表情包就用到瞭解壓縮,從網路下載的那麼多表情文件格式並不是一個一個圖片文件,而是多個圖片壓縮而成的表情壓縮包。下麵介紹的是iOS開發中會用到的壓縮和解壓縮的第三方框架的使用。 註意: 這個第三方框架代碼文件夾是SSZipArchive,使用cocoapods搜索也是搜索SSZipArch
  • in 和 exists 已經成為我們日常查詢時候的常客了。很多時候他們2個都是可以互通實現的,但是,無論兄弟怎麼親,還是會有那麼一些差別的。 先搞個測試表 CREATE TABLE #Tmp1(ID INT,Col1 NVARCHAR(50)) CREATE TABLE #Tmp2(ID INT,T
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...