個人博客
整理mongodb文檔:find方法查詢數據
求關注,求批評,求指出,如果哪兒不清晰,請指出來,謝謝
文章概敘
如題,本文講的是如何用find查詢數據,如何在數組、字段、對象中查詢,以及‘或’等查詢操作,最后講了一些參數。依舊是在shell下操作。
數據準備
查詢數據是db操作中很重要的一步,而mongodb又是Nosql的代表。所以,準備了兩條數據,分別是有string,array,number,object的,方便后面的操作以及講解。
[{"string": "str1","num": 1,"obj": { 'name1': 'value1' },"arr": ["arr11", 'arr12']
},
{"string": "str2","num": 2,"obj": { 'name2': 'value2' },"arr": ["arr21", 'arr22']
}]
find
Selects documents in a collection or view and returns a cursor to the
selected documents.
大概意思就是選擇集合或視圖中的文檔,并將光標返回到所選文檔。
首先來個最簡單的用法,直接使用find方法查詢出所有的數據,讓大家有個直觀的了解
db.test.find()
數據查詢成功,但是這樣子我們查詢出來的是整個表的數據,實際開發中很少這樣子做。畢竟一個表幾個億的數據是很正常的,而我們再看下文檔中關于find方法的描述
看出來,有兩個參數,第一個是我們的查詢條件,第二個是我們的返回字段操作
字段查詢
假定一個例子,我們只需要查詢出num為1的數據,那么我們可以這樣子
db.test.find({ num: 1 })
這樣子,我們就查詢出了我們想要的那條數據,而如果存在多條數據的num都為1,我們可以再增加一些查詢的條件,如下:
db.test.find({num: 1,string: 'str1'
})
這樣子的意思,就是查詢string為str1,并且num為1的數據。相當于我們的‘并’查詢,既然有‘并’查詢,那么就有‘或’查詢,假設我們要查詢num為1或則2的數據,我們的查詢條件可以這么寫:
db.test.find({"$or": [{ num: 1 }, { num: 2 }]
})
db.test.find({num: { "$in": [1, 2] }
})
根據字面意思,第一個sql的意思是一個‘或’操作,其中滿足num為1或則2的時候,而第二個sql的意思則是如果num這個字段是在我們的1,2這兩個之間的時候返回,兩者實現的效果是一樣的,但是可以看到or的操作是先把操作符放在外層,然后再將可能的條件列舉出來,而in的操作是具體對某個字段的操作。這兩個的用法需要注意下。
講述完了"$or"的用法,接下里再講解下如果必須加入其他條件以及正則的使用,正則的使用很重要,在我們做sql查詢的時候,我們要匹配數據經常用到。
舉個例子,現在我們還需要string字段為‘1’結尾的,sql應該如下:
db.test.find({string:/1$/,"$or": [{ num: 1 }, { num: 2 }]
})
有正則經驗的朋友可以理解出,/1$/是正則的寫法,意思就是1結尾,上述的sql是滿足string以1結尾,且存在num為1或則num為2的情況。
講解完了’ o r ′ 以 及 ′ or'以及' or′以及′in’這兩個比較重要的,還有正則的,剩下的是’ l t ′ 、 ′ lt'、' lt′、′gt’等用法,這個建議大家自己按照我的例子去敲一下。官網有很明確的文檔講到這幾個的作用,當然,不大明確的,可以在下面跟我留言。我給個鏈接(最主要希望大家自己學習怎么查找文檔)。
對象查詢
字段的查詢是最簡單的,基本只要用鍵值對的形式查詢就可以,但對于新手來說,對象查詢肯定會一臉懵逼,下面就用一個sql講解如何使用對象查詢
db.test.find({"obj.name1": "value1"
})
可以看到,與上面的字段查詢相比,我們將原來的‘string’變成了’obj.name1’,然后就查出了obj中name為value1的那條數據,看…多簡單。
數組查詢
本質上來說,對象跟數組是沒有區別的,因為數組也是對象的一種,一種key為數字,但是被我們"忽略"掉的key,所以我們使用也可以使用
db.test.find({"arr.0": "arr1"
})
這樣子看起來很奇怪,但是能不能查詢出我們剛剛那條數據呢?很明顯,是可以的
但是我們實際開發中怎么保證數組的第一個數據(key為0的那條)是arr11呢?所以我們一般會用下面的方法去查詢
db.test.find({"arr": "arr11"
})
沒啥好解說的,非要理解,就是遍歷,查看每一條的arr字段,看看是不是數組類型,是的話就看看有沒有arr11這個值這樣子。
字段篩選
講解完了查詢的條件,就輪到了字段的篩選了,舉一個例子,我們只需要返回string這個字段,那么我們可以用下面的sql
db.test.find({ string: "str1" },{ string: 1 }
)
第一個參數我們之前講過了,也就是查詢的條件,這兒的意思是只要string的值為str1的數據。
第二個參數的意思是返回string參數,其中有兩個值,分別是1和0。1代表的是要返回,0代表的是不要返回。
這兒可以看到,雖然沒有設置,但是還是返回了_id,畢竟人家是唯一id,比較牛逼,所以有點特權很正常。那么按照上述所說的,我們不想要返回_id,可以設置下面這樣子
db.test.find({ string: "str1" },{ string: 1, "_id": 0 }
)
但是呢,部分朋友應該知道一條規則,就是0跟1是不能同時出現的,不然會出現很奇怪的情況,比如(我這兒是在很正經的科普mongodb,請不要想歪)
db.test.find({ string: "str1" },{"obj": 1,string:0}
)
意思就是你不能在進來的時候還出去。
除此之外,我們也可以使用下面這種情況
db.test.find({},{"obj.name1": 1,}
)
意思就是我只要返回obj對象的name1,這么做原因也很簡單,部分人會將頭像之類圖片轉化為base64,然后將字符串插入到db中,導致返回的數據過多的時候卡死,而這樣做就可以讓我們只拿到想要的數據。
collation
講解完了mongodb的find方法,大家可能發現,我之前一直講的參數collation在這兒好像沒有了,但是collation的重要性又不言而喻,所以mongodb更不可能放棄它,尤其是在find這種最需要它的api中。所以這兒提一嘴如何使用collaion。
db.test.find().collation({ locale: 'simple' })
整理mongodb文檔:collation
cursor
對于游標,我不大想介紹(我后面可能會寫一個關于游標這個設計的博客,本文主要設計的是查詢數據,我不想超過十分鐘)。
大概理解為它是一個指針,就像是linux的軟連接、c的指針,當我們拿到它的時候,它只是一串地址,指向那條我們想要的數據,當我們真正想要操作數據的時候,它會帶我們去到那個文件的地方,是一個很棒的設計。
請記住一點,我們的數據都是在shell中找到的,所以我們返回的都是一個一個游標,具體請看上面所說的
Selects documents in a collection or view and returns a cursor to the
selected documents.
所以我們在代碼中需要加一個toJSON或是toArray來將其轉化,不過,我們更多是使用lean方法。
好消息是lean() 方法可以幫助我們獲得更快的數據獲取速度,因為它能夠將 MongoDB 查詢結果直接轉化為 JavaScript 對象(或 JSON 字符串)而不需要創建 Mongoose 模型實例。
壞消息是lean只能在find方法中使用。
db.test.find().lean()
最后的啰嗦
增刪改查,沒有一個是不重要的,相對于聚合,索引,集群這些,對于新手增刪改查是最重要的。希望大家能好好敲一遍代碼或者看下項目里的代碼!