1. 程式人生 > >【MongoDB學習筆記】5:對結果集的操作,建立/檢視/重建/刪除索引

【MongoDB學習筆記】5:對結果集的操作,建立/檢視/重建/刪除索引

對結果集的操作

在RDBMS中獲得的結果是一張虛擬的表,可以在其上繼續操作。MongoDB中查詢到的結果是一個文件集合,也可以在其上做一些簡單操作。

limit()方法

相當於SQL中的TOP子句,會取結果集中的前指定條文件,使用

結果集.limit(數字n)

能獲取結果集中的前n條文件。

> db.lzhCllctn1.find()
{ "_id" : ObjectId("5b29dedaf5b9d062d3a61e61"), "a" : 1 }
{ "_id" : ObjectId("5b29dedcf5b9d062d3a61e62"), "a" : 3 }
{ "_id"
: ObjectId("5b29dedef5b9d062d3a61e63"), "a" : 4 } { "_id" : ObjectId("5b29dee1f5b9d062d3a61e64"), "a" : 3 } { "_id" : ObjectId("5b29dee8f5b9d062d3a61e65"), "a" : 2 } > db.lzhCllctn1.find().limit(3) { "_id" : ObjectId("5b29dedaf5b9d062d3a61e61"), "a" : 1 } { "_id" : ObjectId("5b29dedcf5b9d062d3a61e62"
), "a" : 3 } { "_id" : ObjectId("5b29dedef5b9d062d3a61e63"), "a" : 4 } >

skip()方法

使用

結果集.skip(數字n)

能跳過結果集中的前n條文件,獲取其後的全部文件。

> db.lzhCllctn1.find()
{ "_id" : ObjectId("5b29dedaf5b9d062d3a61e61"), "a" : 1 }
{ "_id" : ObjectId("5b29dedcf5b9d062d3a61e62"), "a" : 3 }
{ "_id" : ObjectId("5b29dedef5b9d062d3a61e63"
), "a" : 4 } { "_id" : ObjectId("5b29dee1f5b9d062d3a61e64"), "a" : 3 } { "_id" : ObjectId("5b29dee8f5b9d062d3a61e65"), "a" : 2 } > db.lzhCllctn1.find().skip(3) { "_id" : ObjectId("5b29dee1f5b9d062d3a61e64"), "a" : 3 } { "_id" : ObjectId("5b29dee8f5b9d062d3a61e65"), "a" : 2 } >

看來skip()和limit()相配合,就能一塊一塊的訪問結果集中的文件了,如完成網頁商品的分頁效果大概可以用這個。

limit()和skip()的優先性

不能想當然地認為這兩個方法的呼叫順序會影響結果,不會。limit()skip()一起使用時,總是先skip()limit()

> db.lzhCllctn1.find()
{ "_id" : ObjectId("5b29dedaf5b9d062d3a61e61"), "a" : 1 }
{ "_id" : ObjectId("5b29dedcf5b9d062d3a61e62"), "a" : 3 }
{ "_id" : ObjectId("5b29dedef5b9d062d3a61e63"), "a" : 4 }
{ "_id" : ObjectId("5b29dee1f5b9d062d3a61e64"), "a" : 3 }
{ "_id" : ObjectId("5b29dee8f5b9d062d3a61e65"), "a" : 2 }
> db.lzhCllctn1.find().limit(3).skip(1)
{ "_id" : ObjectId("5b29dedcf5b9d062d3a61e62"), "a" : 3 }
{ "_id" : ObjectId("5b29dedef5b9d062d3a61e63"), "a" : 4 }
{ "_id" : ObjectId("5b29dee1f5b9d062d3a61e64"), "a" : 3 }
> db.lzhCllctn1.find().skip(1).limit(3)
{ "_id" : ObjectId("5b29dedcf5b9d062d3a61e62"), "a" : 3 }
{ "_id" : ObjectId("5b29dedef5b9d062d3a61e63"), "a" : 4 }
{ "_id" : ObjectId("5b29dee1f5b9d062d3a61e64"), "a" : 3 }
>

sort()方法

sort可以指定排序的欄位,用1表示升序,-1表示降序,即

結果集.sort({排序key:1或-1})

> db.lzhCllctn1.find()
{ "_id" : ObjectId("5b29dedaf5b9d062d3a61e61"), "a" : 1 }
{ "_id" : ObjectId("5b29dedcf5b9d062d3a61e62"), "a" : 3 }
{ "_id" : ObjectId("5b29dedef5b9d062d3a61e63"), "a" : 4 }
{ "_id" : ObjectId("5b29dee1f5b9d062d3a61e64"), "a" : 3 }
{ "_id" : ObjectId("5b29dee8f5b9d062d3a61e65"), "a" : 2 }
> db.lzhCllctn1.find().sort({a:1})
{ "_id" : ObjectId("5b29dedaf5b9d062d3a61e61"), "a" : 1 }
{ "_id" : ObjectId("5b29dee8f5b9d062d3a61e65"), "a" : 2 }
{ "_id" : ObjectId("5b29dedcf5b9d062d3a61e62"), "a" : 3 }
{ "_id" : ObjectId("5b29dee1f5b9d062d3a61e64"), "a" : 3 }
{ "_id" : ObjectId("5b29dedef5b9d062d3a61e63"), "a" : 4 }
> db.lzhCllctn1.find().sort({a:-1})
{ "_id" : ObjectId("5b29dedef5b9d062d3a61e63"), "a" : 4 }
{ "_id" : ObjectId("5b29dedcf5b9d062d3a61e62"), "a" : 3 }
{ "_id" : ObjectId("5b29dee1f5b9d062d3a61e64"), "a" : 3 }
{ "_id" : ObjectId("5b29dee8f5b9d062d3a61e65"), "a" : 2 }
{ "_id" : ObjectId("5b29dedaf5b9d062d3a61e61"), "a" : 1 }
>

可以看到排序比較上相同的文件總是按_id從小到大進行排序。

limit()和skip()和sort()的優先性

總是先sort(),再skip(),最後limit(),不論它們的書寫順序如何。

> db.lzhCllctn1.find()
{ "_id" : ObjectId("5b29dedaf5b9d062d3a61e61"), "a" : 1 }
{ "_id" : ObjectId("5b29dedcf5b9d062d3a61e62"), "a" : 3 }
{ "_id" : ObjectId("5b29dedef5b9d062d3a61e63"), "a" : 4 }
{ "_id" : ObjectId("5b29dee1f5b9d062d3a61e64"), "a" : 3 }
{ "_id" : ObjectId("5b29dee8f5b9d062d3a61e65"), "a" : 2 }
> db.lzhCllctn1.find().limit(3).sort({a:-1}).skip(1)
{ "_id" : ObjectId("5b29dedcf5b9d062d3a61e62"), "a" : 3 }
{ "_id" : ObjectId("5b29dee1f5b9d062d3a61e64"), "a" : 3 }
{ "_id" : ObjectId("5b29dee8f5b9d062d3a61e65"), "a" : 2 }
> db.lzhCllctn1.find().sort({a:-1}).skip(1).limit(3)
{ "_id" : ObjectId("5b29dedcf5b9d062d3a61e62"), "a" : 3 }
{ "_id" : ObjectId("5b29dee1f5b9d062d3a61e64"), "a" : 3 }
{ "_id" : ObjectId("5b29dee8f5b9d062d3a61e65"), "a" : 2 }
>

索引

為什麼使用索引

不使用索引時,查詢需要做代價比較高的順序掃描。MongoDB中的索引可以建立一種按某些欄位的某種排序規則進行排序的資料結構,如果這種排序能讓業務內常用的查詢變快(如部落格/新聞網站時常需要按時間降序排序),那麼只要花費一次建立索引的時間(這個時間可能比較長),就能帶來MongoDB資料庫在該業務下的效能提升。

建立索引

在要建立索引的DB下,使用

db.集合名.createIndex(
    {
        排序key1:升1降-1,
        排序key2:升1降-1,
        ...
    },
    {
        background:是否將建立索引操作放入後臺,
        unique:建立的索引是否唯一,
        name:顯式指明索引名稱,
        v:索引的版本號,
        weights:該索引相對於其它索引的重要權重,
        default_language:文字索引停用詞規則,
        language_override:文字索引包含在文件中的欄位名,
        expireAfterSeconds:集合的生存時間
    }
)

來建立一個索引,其中第二個BSON體及其中的引數是可選的。當在第一個BSON體內使用多個排序規則時,相當於RDBMS中的複合索引。

特別注意,runoob和其它教程中提及的

dropDups:是否刪除重複記錄以建立唯一索引

這一選項從MongoDB2.7.5開始就已經廢棄了,大多教程都沒有更新,甚至在使用老舊的ensureIndex(),目前它就是指向createIndex()

> db.lzhCllctn1.createIndex({a:1})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}
>

檢視索引

在要檢視索引的DB下,使用

db.集合名.getIndexes()

檢視該集合的所有索引。

使用

db.集合名.totalIndexSize()

檢視集合中所有索引的總大小。

> db.lzhCllctn1.getIndexes()
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "lzh.lzhCllctn1"
        },
        {
                "v" : 2,
                "key" : {
                        "a" : 1
                },
                "name" : "a_1",
                "ns" : "lzh.lzhCllctn1"
        }
]
> db.lzhCllctn1.totalIndexSize()
53248
>

可以看到剛剛為a欄位建立的索引,而主鍵_id的索引是MongoDB自動建立的。

重建索引

MongoDB和熱門的RDBMS一樣是用B-tree做索引。索引需要重建是因為對資料庫的某些操作可能破壞索引或產生索引碎片,讓索引帶來的效能下降。具體的重建時機是比較高階的部分,涉及對索引當前情況的分析,以後再細學。

在要重建索引的DB下,使用

db.集合名.reIndex()

為該集合重建索引。

> db.lzhCllctn1.reIndex()
{
        "nIndexesWas" : 2,
        "nIndexes" : 2,
        "indexes" : [
                {
                        "v" : 2,
                        "key" : {
                                "_id" : 1
                        },
                        "name" : "_id_",
                        "ns" : "lzh.lzhCllctn1"
                },
                {
                        "v" : 2,
                        "key" : {
                                "a" : 1
                        },
                        "name" : "a_1",
                        "ns" : "lzh.lzhCllctn1"
                }
        ],
        "ok" : 1
}
>

刪除索引

從前面可以看到,索引都是有唯一的name欄位的,可以在建立索引時顯式指定,也可以由MongoDB來指定。

在要刪除索引的DB下,使用

db.集合名.dropIndex('要刪除的索引的name')

來刪除指定name的索引。

使用

db.集合名.dropIndexes()

刪除集合中的所有索引。

> db.lzhCllctn1.getIndexes()
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "lzh.lzhCllctn1"
        },
        {
                "v" : 2,
                "key" : {
                        "a" : 1
                },
                "name" : "a_1",
                "ns" : "lzh.lzhCllctn1"
        }
]
> db.lzhCllctn1.dropIndex('a_1')
{ "nIndexesWas" : 2, "ok" : 1 }
> db.lzhCllctn1.getIndexes()
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "lzh.lzhCllctn1"
        }
]
> db.lzhCllctn1.dropIndexes()
{
        "nIndexesWas" : 1,
        "msg" : "non-_id indexes dropped for collection",
        "ok" : 1
}
> db.lzhCllctn1.getIndexes()
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "lzh.lzhCllctn1"
        }
]
>

可以看到,MongoDB為主鍵_id建立的預設索引不能被刪除。

相關推薦

MongoDB學習筆記5結果操作,建立/檢視/重建/刪除索引

對結果集的操作 在RDBMS中獲得的結果是一張虛擬的表,可以在其上繼續操作。MongoDB中查詢到的結果是一個文件集合,也可以在其上做一些簡單操作。 limit()方法 相當於SQL中的TOP子句,會取結果集中的前指定條文件,使用 結果集.limit(數

TensorFlow學習筆記5variable_scope和name_scope,圖的基本操作

學習《深度學習之TensorFlow》時的一些實踐。 variable_scope 一般的巢狀 上節有學到在巢狀scope中的變數,一般是: import tensorflow as tf # with tf.variable_scope("scopeA") as

MyBatis學習筆記5認識使用typeHandlers配置型別處理器

簡述 註冊了的型別處理器會用於處理下面兩種情形: 為PreparedStatement設定一個引數,將引數從Java型別轉為JDBC型別。 從ResultSet中取出一個值,將結果從JDBC型別轉為Java型別。 型別處理器可分為以下兩類: MyB

ML學習筆記5機器學習中的數學基礎5(張量,哈達瑪積,生成子空間,超平面,範數)

向量/矩陣/張量 向量 向量可以表示成一維陣列,每個分量可以理解為向量所表示的點在空間中座標的分量。 矩陣 矩陣可以表示成二維陣列,上節理解了矩陣可以理解為線性對映在特定基下的一種定量描述。 張量 張量可以表示成任意維的陣列,張量是向量概

MongoDB學習筆記1在Windows上的安裝和配置

NOSQL就是Not Only SQL,MongoDB是一個很好的學習NOSQL的起點。 下載 可以在MongoDB官網選擇Community Server版本下載,但是它似乎經常沒有響應。可以在這裡直接選擇需要的版本下載,要在Windows下安裝可以直

MongoDB學習筆記6資料備份(mongodump)與恢復(mongorestore)流程

備份資料 要備份某個DB中的全部Collection,相當於備份RDBMS中某個Schema下的全部Table。比如想要備份這個DB: > show dbs admin 0.000GB config 0.000GB local 0.000

python學習筆記39認識SQLAlchemy,簡單操作Pandas中的DataFrame

學習《Python3爬蟲、資料清洗與視覺化實戰》時自己的一些實踐。 認識SQLAlchemy SQLAlchemy是Python的ORM工具,就像Java有Hibernate一樣,實現關係型資料庫中的記錄與Python自定義Class的物件的轉化,實現操作之間的對映。

JAVAEE學習筆記hibernate02實體規則、象狀態、緩存、事務、批量查詢和實現客戶列表顯示

使用 ins tro trace ges create 綁定 criteria 命名 一、hibernate中的實體規則 實體類創建的註意事項  1.持久化類提供無參數構造  2.成員變量私有,提供共有get/set方法訪問.需提供屬性  3.持久化類中的屬性,應盡量使用包

SciKit-Learn學習筆記5核SVM分類和預測乳腺癌資料

學習《scikit-learn機器學習》時的一些實踐。 常用引數 引數C SVM分類器svm.SVC()中的引數C即SVM所優化的目標函式 a

Vue.js學習筆記5雙向資料繫結,計算屬性

雙向資料繫結 雙向資料繫結往往會用到input、select、textarea等表單標籤上,因為總是涉及一個數據資料的地方和輸出資料的地方。 當資料發生變化的時候,檢視也就發生變化,當檢視發生變化的時候,資料也會跟著同步變化。 資料雙向繫結,一定是對於UI控制元件來說的,

SQL Server學習筆記5使用INSERT語句插入資料

使用SQL語句的意義是,要開發的DBAS應用程式不能像人一樣通過SSMS工具來操作資料,SQL語句是應用程式和資料庫通訊的橋樑。而且相比手動圖形化操作,SQL語句更加方便和強大。 SQL(結構化查詢語言)的組成 ①DML(資料操作語言) 插入、刪除和修

JAVAEE學習筆記hibernate03多表操作,級聯練習:添加聯系人

row tac 默認值 rac user except pro intra com 一、一對多|多對一 1、關系表達  表中的表達      實體中的表達      orm元數據中表達     一對多 <!-- 集合,一對多關系,在配置文件中配置 -

JAVAEE學習筆記hibernate04查詢種類、HQL、Criteria、查詢優化和練習為客戶列表增加查詢條件

沒有 arrays getpara tex response 寫法 sum exceptio 提高 一、查詢種類 1.oid查詢-get 2.對象屬性導航查詢 3.HQL 4.Criteria 5.原生SQL 二、查詢-HQL語法 //學習HQL語法 public

K8S學習筆記Part3同一Pod中多個容器間使用共享卷進行通信

ash source net def exe tput stat policy container 本文將展示如何使用共享卷(Volume)來實現相同Pod中的兩個容器間通信。 註意:本文針對K8S的版本號為v1.9,其他版本可能會有少許不同。 0x00 準備工作 需要有一

python學習筆記37認識Scrapy爬蟲,爬取滬深A股資訊

學習《Python3爬蟲、資料清洗與視覺化實戰》時自己的一些實踐。 認識Scrapy爬蟲 安裝 書上說在pip安裝會有問題,直接在Anaconda裡安裝。 建立Scrapy專案 PyCharm裡沒有直接的建立入口,在命令列建立(從Anaconda安裝後似乎自動就

python學習筆記36抓取去哪兒網的旅遊產品資料

學習《Python3爬蟲、資料清洗與視覺化實戰》時自己的一些實踐。 書上這章開篇就說了儘量找JSON格式的資料,比較方便解析(在python裡直接轉換成字典),去哪兒網PC端返回的不是JSON資料,這裡抓取的是它的移動端的資料。 如果是就散落在網頁上,我覺得就像上篇學習的那

python學習筆記35爬蟲基礎和相關產品API(和風天氣)使用例項

學習《Python3爬蟲、資料清洗與視覺化實戰》時自己的一些實踐。 在網站URL後面跟robots.txt一般就可以看到網站允許和禁止爬取的資源。 GET請求獲取響應內容 最基本的爬蟲。 import requests ''' 中國旅遊網 /www.cntour.

python學習筆記41認識Pandas中的資料變形

學習《Python3爬蟲、資料清洗與視覺化實戰》時自己的一些實踐。 Pandas資料變形 關於stack()和unstack()見這裡和這裡。 import pandas as pd import numpy as np # 讀取杭州天氣檔案 df = pd.read

python學習筆記40Pandas中DataFrame的分組/分割/合併

學習《Python3爬蟲、資料清洗與視覺化實戰》時自己的一些實踐。 DataFrame分組操作 注意分組後得到的就是Series物件了,而不再是DataFrame物件。 import pandas as pd # 還是讀取這份檔案 df = pd.read_csv("

python學習筆記38使用Selenium抓取去哪兒網動態頁面

學習《Python3爬蟲、資料清洗與視覺化實戰》時自己的一些實踐。 在去哪兒網PC端自由行頁面,使用者需要輸入出發地和目的地,點選開始定製,然後就可以看到一系列相關的旅遊產品。在這個旅遊產品頁換頁不會改變URL,而是重新載入,這時頁碼沒有體現在URL中,這種動態頁面用傳統的爬蟲