英文原文位址:https://docs.mongodb.com/v3.2/tutorial/query-documents/。
本文章屬個人翻譯,作個人學習之用,如有雷同,純屬巧合。如有錯誤之處,歡迎指正。
查詢文檔
查詢方法
MongoDB提供了
db.collection.find()
方法來從集合中讀取文檔。
db.collection.find()
方法傳回所比對文檔的
遊标
。
db.collection.find(<query filter>, <projection>)
你可以指定以下可選字段:
- 查詢過濾器,指定傳回的文檔
- 投影,指定從比對的文檔傳回哪些字段。投影限制了MongoDB通過網絡傳回給用戶端的資料量大小。
你可以選擇性地添加一個遊标修飾符來強制性地限制傳回條數(limit)、跳過集合個數(skip),以及排序(sort)。除非你指定
sort()
,否則傳回文檔的順序是不确定的。
示例集合
本文的例子在
mongo
shell中使用
db.collection.find()
方法。在
mongo
shell中,如果傳回的遊标沒有用var關鍵字指派給變量,則遊标自動疊代至20次,列印結果的前20個文檔。
為填充本例子中所提到的
users
集合,請在
mongo
shell中運作一下代碼:
注意
如果
集合已經包含了相同_id的集合,插入文檔前需要删除該集合(
users
)
db.users.drop()
db.users.insertMany( [ { _id: 1, name: "sue", age: 19, type: 1, status: "P", favorites: { artist: "Picasso", food: "pizza" }, finished: [ 17, 3 ], badges: [ "blue", "black" ], points: [ { points: 85, bonus: 20 }, { points: 85, bonus: 10 } ] }, { _id: 2, name: "bob", age: 42, type: 1, status: "A", favorites: { artist: "Miro", food: "meringue" }, finished: [ 11, 25 ], badges: [ "green" ], points: [ { points: 85, bonus: 20 }, { points: 64, bonus: 12 } ] }, { _id: 3, name: "ahn", age: 22, type: 2, status: "A", favorites: { artist: "Cassatt", food: "cake" }, finished: [ 6 ], badges: [ "blue", "red" ], points: [ { points: 81, bonus: 8 }, { points: 55, bonus: 20 } ] }, { _id: 4, name: "xi", age: 34, type: 2, status: "D", favorites: { artist: "Chagall", food: "chocolate" }, finished: [ 5, 11 ], badges: [ "red", "black" ], points: [ { points: 53, bonus: 15 }, { points: 51, bonus: 15 } ] }, { _id: 5, name: "xyz", age: 23, type: 2, status: "D", favorites: { artist: "Noguchi", food: "nougat" }, finished: [ 14, 6 ], badges: [ "orange" ], points: [ { points: 71, bonus: 20 } ] }, { _id: 6, name: "abc", age: 43, type: 1, status: "A", favorites: { food: "pizza", artist: "Picasso" }, finished: [ 18, 12 ], badges: [ "black", "blue" ], points: [ { points: 78, bonus: 8 }, { points: 57, bonus: 7 } ] } ] )
查詢集合中的所有文檔
一個空的
查詢過濾文檔
(
{}
)選中集合中的所有文檔:
db.users.find( {} )
db.collection.find()
中省略查詢過濾文檔等價于指定一個空的查詢文檔。這樣的話,以下操作等價于前面的操作:
db.users.find()
指定查詢過濾條件
指定等于條件
查詢過濾文檔
可以用
<filed>:<value>
表達式指定等于條件,選擇所有包含字段,且其值等于
<value>
的文檔
{ <field1>: <value1>, ...}
以下例子從
users
集合中傳回值字段status值為”A”的所有文檔:
db.users.find( {status: "A"} )
用查詢運算符指定條件
查詢過濾文檔
可以用
查詢運算符
來指定條件,格式如下:
{ <field>: { <operator1>: <value1>}, ...}
以下例子從
users
集合中傳回status字段等于”P”或”D”的文檔。
db.users.find( {status: {$in: ["P", "D"]}} )
雖然你可以用
$or
運算符來表達這個查詢,在相同的字段上執行相等性檢查時,用
$in
,而不是用
$or
。
欲知完整的查詢運算符清單,請參考查詢與投影運算符。
指定 AND 條件
一個複合查詢可以在文檔的多個字段中指定查詢條件。邏輯操作符AND把複合查詢的各部分連接配接起來,使得該查詢能夠選中集合中滿足所有條件的文檔。
以下例子從
users
集合中傳回所有status等于”A”**與**age小于30的文檔:
db.users.find( {status: "A", age: {$lt: 30}} )
指定OR條件
通過
$or
運算符,你可以用邏輯OR來連接配接複合查詢中的各部分,使得該查詢能夠選中集合中滿足其中至少一個條件的文檔。
以下例子從
users
集合中傳回所有status等于”A”**或**age小于30的文檔:
db.users.find( [ $or: [{status: "A"}, {age: {$lt: 30}}] ] )
同時指定AND和OR條件
通過額外的從句,你可以為比對文檔指定精确的條件。
以下例子中,複合查詢文檔從集合中選擇status等于”A”,并且age小于30或者type等于1的記錄。
db.users.find( { status: "A", $or: [{age: {$lt: 30}}, {type: 1}] } )
在嵌入文檔中查詢
當字段包含一個嵌入文檔時,查詢可以在嵌入文檔上指定一個精确比對,也可以用
點标記法
在嵌入文檔上通過單獨的字段來指定比對。
精确比對嵌入文檔
要在整個嵌入文檔中指定精确比對,使用 {
<field>
:
<value>
},其中,
<value>
是比對的文檔。在嵌入文檔中做相等比對,指定的
<value>
必須精确比對文檔,包括字段順序。
在以下例子中,該查詢比對所有的文檔:favorites字段是一個隻包含artist字段,其值等于”Picasso”,和food字段,其值等于”pizza”的嵌入文檔,按照 artist、food的順序:
db.users.find( {favorites: {artists: "Picasso", food: "pizza"}} )
相等比對嵌入文檔的字段
可以用
點标記法
來比對嵌入文檔中的指定字段。嵌入文檔内指定字段的相等性比對會選中包含具有指定的值的指定字段的嵌入文檔,嵌入文檔可以包含其他字段。
以下例子中,該查詢使用
點标記法
來比對favorites字段是一個包含值等于”Picasso”的artist字段,可能還可以包含其他字段的嵌入文檔的所有文檔。
db.users.find( {"favorites.artist": "Picasso"} )
在數組上的查詢
當字段的值是一個數組時,你可以指定比對整個數組,或者數組中的指定值。如果數組包含嵌入文檔,你可以使用
點标記法
查詢嵌入文檔中的指定字段。
如果你使用
$elemMatch
操作符指定多個條件,該數組必須至少包含一個滿足所有條件的元素。見 單個元素滿足條件。
如果你不用
$elemMatch
指定多個條件,則數組元素的某個組合必須滿足所有條件,單個元素不一定都需要滿足,即,不同的數組元素可以滿足條件的不同部分。見 元素的組合滿足條件。
精确比對整個數組
要指定數組的相等比對,用查詢文檔
{ <field>: <value> }
,其中
<value>
是要比對的數組。精确比對一個數組需要滿足:數組必須精确比對指定的
<value>
,包括元素順序。
以下例子查詢badges字段是一個按順序包含”blue”和”black”兩個元素的數組的文檔:
db.users.find( {badges: ["blue", "black"]} )
該查詢傳回以下文檔:
{ "_id" : 1, "name" : "sue", "age" : 19, "type" : 1, "status" : "P", "favorites" : { "artist" : "Picasso", "food" : "pizza" }, "finished" : [ 17, 3 ] "badges" : [ "blue", "black" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 85, "bonus" : 10 } ] }
比對數組的一個元素
相等性比對也可以指定比對數組中的單個元素。隻要數組中至少一個元素的值等于指定的值就行。
以下例子查詢badges字段是一個包含”black”元素的數組的文檔。
db.users.find( { badges: "black" } )
該查詢傳回以下文檔:
{ "_id" : 1, "name" : "sue", "age" : 19, "type" : 1, "status" : "P", "favorites" : { "artist" : "Picasso", "food" : "pizza" }, "finished" : [ 17, 3 ] "badges" : [ "blue", "black" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 85, "bonus" : 10 } ] } { "_id" : 4, "name" : "xi", "age" : 34, "type" : 2, "status" : "D", "favorites" : { "artist" : "Chagall", "food" : "chocolate" }, "finished" : [ 5, 11 ], "badges" : [ "red", "black" ], "points" : [ { "points" : 53, "bonus" : 15 }, { "points" : 51, "bonus" : 15 } ] } { "_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : { "food" : "pizza", "artist" : "Picasso" }, "finished" : [ 18, 12 ], "badges" : [ "black", "blue" ], "points" : [ { "points" : 78, "bonus" : 8 }, { "points" : 57, "bonus" : 7 } ] }
比對數組中的指定元素
相等性比對也可以用
點标記法
指定比對數組中特定下标或位置的元素。
以下例子中,該查詢使用
點标記法
比對badges字段是一個”black”作為第一個元素的數組的文檔。
db.users.find( { "badges.0": "black" } )
該操作傳回以下結果:
{ "_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : { "food" : "pizza", "artist" : "Picasso" }, "finished" : [ 18, 12 ], "badges" : [ "black", "blue" ], "points" : [ { "points" : 78, "bonus" : 8 }, { "points" : 57, "bonus" : 7 } ] }
給數組元素指定多個條件
單個元素滿足條件
使用
$elemMatch
操作符來在數組元素上指定多個條件,至少一個數組元素滿足所有條件即可。
以下例子查詢字段finished是一個至少一個元素大于15且小于20的數組的文檔。
db.users.find( { finished: { $elemMatch: { $gt: 15, $lt: 20 } } } )
該操作傳回以下文檔,其finished字段是一個數組,至少一個元素滿足條件。
{ "_id" : 1, "name" : "sue", "age" : 19, "type" : 1, "status" : "P", "favorites" : { "artist" : "Picasso", "food" : "pizza" }, "finished" : [ 17, 3 ] "badges" : [ "blue", "black" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 85, "bonus" : 10 } ] } { "_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : { "food" : "pizza", "artist" : "Picasso" }, "finished" : [ 18, 12 ], "badges" : [ "black", "blue" ], "points" : [ { "points" : 78, "bonus" : 8 }, { "points" : 57, "bonus" : 7 } ] }
數組元素的組合滿足條件
以下例子查詢這樣的文檔:其finished是一個數組,并且這個數組包含的元素的組合滿足查詢條件。即,一個元素滿足大于15這個條件,而另外一個元素滿足小于20這個條件,或者單個元素就滿足這兩個條件。
db.users.find( { finished: { $gt: 15, $lt: 20 } } )
該操作傳回以下結果:
{ "_id" : 1, "name" : "sue", "age" : 19, "type" : 1, "status" : "P", "favorites" : { "artist" : "Picasso", "food" : "pizza" }, "finished" : [ 17, 3 ] "badges" : [ "blue", "black" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 85, "bonus" : 10 } ] } { "_id" : 2, "name" : "bob", "age" : 42, "type" : 1, "status" : "A", "favorites" : { "artist" : "Miro", "food" : "meringue" }, "finished" : [ 11, 20 ], "badges" : [ "green" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 64, "bonus" : 12 } ] } { "_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : { "food" : "pizza", "artist" : "Picasso" }, "finished" : [ 18, 12 ], "badges" : [ "black", "blue" ], "points" : [ { "points" : 78, "bonus" : 8 }, { "points" : 57, "bonus" : 7 } ] }
嵌入文檔組成的數組
用數組下标比對嵌入文檔中的字段
如果你知道嵌入文檔在數組中的下标,你可以用
點标記法
來指明嵌入文檔的位置。
以下例子選擇這樣的文檔:其points字段是一個數組,數組的第一個元素是一個文檔,該文檔包含points字段,其值小于或等于55。
db.users.find( { 'points.0.points': { $lte: 55 } } )
該操作傳回以下文檔:
{ "_id" : 4, "name" : "xi", "age" : 34, "type" : 2, "status" : "D", "favorites" : { "artist" : "Chagall", "food" : "chocolate" }, "finished" : [ 5, 11 ], "badges" : [ "red", "black" ], "points" : [ { "points" : 53, "bonus" : 15 }, { "points" : 51, "bonus" : 15 } ] }
不指定數組下标來比對字段
如果你不知道數組中文檔的下标,你可以用”.”把這個數組的字段名和嵌入文檔中的字段名連起來。
以下例子查詢這樣的文檔:其points是一個數組,這個數組中的至少一個嵌入文檔包含points字段,這個字段的值小于或等于55:
db.users.find( { 'points.points': { $lte: 55 } } )
該操作傳回以下結果:
{ "_id" : 3, "name" : "ahn", "age" : 22, "type" : 2, "status" : "A", "favorites" : { "artist" : "Cassatt", "food" : "cake" }, "finished" : [ 6 ], "badges" : [ "blue", "red" ], "points" : [ { "points" : 81, "bonus" : 8 }, { "points" : 55, "bonus" : 20 } ] } { "_id" : 4, "name" : "xi", "age" : 34, "type" : 2, "status" : "D", "favorites" : { "artist" : "Chagall", "food" : "chocolate" }, "finished" : [ 5, 11 ], "badges" : [ "red", "black" ], "points" : [ { "points" : 53, "bonus" : 15 }, { "points" : 51, "bonus" : 15 } ] }
給文檔數組指定多個條件
單個元素滿足條件
用
$elemMatch
運算符,在嵌入文檔組成的數組上指定多個條件,篩選出數組中至少一個嵌入文檔滿足所有指定條件的的文檔。
以下例子查詢這樣的文檔:其points字段是一個數組,數組中至少一個嵌入文檔包含值小于或等于70的points字段,和值等于20的bonus字段。
db.users.find( { points: { $elemMatch: { points: { $lte: 70 }, bonus: 20 } } } )
該操作傳回以下文檔:
{ "_id" : 3, "name" : "ahn", "age" : 22, "type" : 2, "status" : "A", "favorites" : { "artist" : "Cassatt", "food" : "cake" }, "finished" : [ 6 ], "badges" : [ "blue", "red" ], "points" : [ { "points" : 81, "bonus" : 8 }, { "points" : 55, "bonus" : 20 } ] }
嵌入文檔元素的組合滿足條件
以下例子查詢這樣的文檔:其points字段是一個數組,數組元素的某個組合滿足查詢條件,即,一個元素的points字段小于或等于70,另一個元素的bonus字段等于20,或者單個元素就滿足這兩個條件。
db.users.find( { "points.points": { $lte: 70 }, "points.bonus": 20 } )
該查詢傳回以下文檔:
{ "_id" : 2, "name" : "bob", "age" : 42, "type" : 1, "status" : "A", "favorites" : { "artist" : "Miro", "food" : "meringue" }, "finished" : [ 11, 20 ], "badges" : [ "green" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 64, "bonus" : 12 } ] } { "_id" : 3, "name" : "ahn", "age" : 22, "type" : 2, "status" : "A", "favorites" : { "artist" : "Cassatt", "food" : "cake" }, "finished" : [ 6 ], "badges" : [ "blue", "red" ], "points" : [ { "points" : 81, "bonus" : 8 }, { "points" : 55, "bonus" : 20 } ] }