mongoose 中的查詢

find()

Model.find(filter[, projection][, options][, callback])html

參數一:filter

查詢條件使用 JSON 文檔的格式,JSON 文檔的語法跟 MongoDB shell 中一致。前端

{ field1: value1, field2: { operator: value2 } ... }mongodb

1. 查找所有

Model.find()
Model.find({})

2. 精確查找

Model.find({author:'dora'})

3. 使用操做符

對比相關操做符shell

符號 描述
$eq 與指定的值相等
$ne 與指定的值不相等
$gt 大於指定的值
$gte 大於等於指定的值
$lt 小於指定的值
$lte 小於等於指定的值
$in 與查詢數組中指定的值中的任何一個匹配
$nin 與查詢數組中指定的值中的任何一個都匹配
Model.find({ age: { $in: [16, 18]} })

返回 age 字段等於 16 或者 18 的全部 document。express

邏輯相關操做符api

符號 描述
$and 知足數組中指定的全部條件
$nor 不知足數組中指定的全部條件
$or 知足數組中指定的條件的其中一個
$not 反轉查詢,返回不知足指定條件的文檔
// 相關語法
{$and:[ {expression1},{expression2}, ... ,{expressionN} ]}
{$nor:[ {expression1},{expression2}, ... ,{expressionN} ]}
{$or:[ {expression1},{expression2}, ... ,{expressionN} ]}
{field: { $not: { <operator-expression> }}}

邏輯操做符中的比較包括字段不存在的狀況。數組

Model.find( { age: { $not: { $lte: 16 }}})
// 返回 age 字段大於 16 或者 age 字段 不存在 的文檔

字段相關操做符promise

符號 描述
$exists 匹配存在指定字段的文檔 { field: { $exists: <boolean> } }
$type 返回字段屬於指定類型的文檔 {field: { $type: <BSON type> }}

4. 嵌套對象字段的查找

數據以下async

{
  name: { first: "dora", last: "wang" }
}

精確匹配,順序、字段都必須一致。mongoose

Model.find({ name: { last: "wang", first: "dora" } })
// [] 找不到數據

使用點語法,可匹配嵌套的字段,其中字段名必須用引號引發來。

Model.find({ 'name.last': 'wang' })

5. 數組字段的查找

符號 描述
$all 匹配包含查詢數組中指定的全部條件的數組字段
$elemMatch 匹配數組字段中的某個值知足 $elemMatch 中指定的全部條件
$size 匹配數組字段的 length 與指定的大小同樣的 document

數據以下

{ year: [ 2018, 2019 ] }
{ year: [ 2017, 2019, 2020 ] }
{ year: [ 2016, 2020 ] }

查找數組中的至少一個值

可以使用精確查找寫法 {field: value}

Model.find({ year: 2019 });
// { "_id" : ..., "year" : [ 2018, 2019 ] }
// { "_id" : ..., "year" : [ 2017, 2019, 2020 ] }

查找數組中的多個值

使用 $all 查找同時存在 20192020document

Model.find({ year: { $all: [ 2019, 2020 ] } });
// { "_id" : ..., "year" : [ 2017, 2019, 2020 ] }

操做符組合查詢

可以使用操做符進行篩選,{<field>:{operator: value}},好比 $in

Model.find({ year: { $in: [ 2018, 2020 ] } });
// { "_id" : ..., "year" : [ 2018, 2019 ] }
// { "_id" : ..., "year" : [ 2017, 2019, 2020 ] }

使用操做符組合查詢 {<field>:{operator1: value1, operator2: value2}}

Model.find({ year: { $gt: 2019, $lt: 2018 } });
// { "_id" : ..., "year" : [ 2017, 2019, 2020 ] }
// { "_id" : ..., "year" : [ 2016, 2020 ] }

數組字段包含知足查詢條件的元素,能夠是不一樣元素分別知足條件也能夠是同一個元素知足全部條件,如上例,是一個值知足大於2019的條件,另外一個值知足小於2018的條件。

$elemMatch 單個字段值知足全部查詢條件

$elemMatch 查找數組字段中的值同時知足全部條件的 document

{field: { $elemMatch: { <query1>, <query2>, ... }}}

Model.find({ year: { $elemMatch: { $gt: 2016, $lt: 2018 } } })
// { "_id" : ..., "year" : [ 2017, 2019, 2020 ] }

數組下標查詢

Model.find({ 'year.1': { $gt: 2019 } })
// { "_id" : ..., "year" : [ 2016, 2020 ] }

數組 year 的第二個值大於2019

6. 數組對象的查找

數據以下

{author: [{name: "dora", age: 18 },{name: "wang", age: 16 }]}

精確查詢

精確匹配,順序、字段都必須一致。

Model.find({ author: { name: "dora", age: 18 } })

點語法查詢

Model.find({ 'author.age': { $gte: 18 } })

$elemMatch 同時知足全部查詢條件

Model.find({ "author": {$elemMatch: {name: 'dora', age:{ $lt: 18 }}})
// []

參數二:projection

指定要包含或排除哪些 document 字段(也稱爲查詢「投影」),必須同時指定包含或同時指定排除,不能混合指定,_id 除外。

在 mongoose 中有兩種指定方式,字符串指定和對象形式指定。

字符串指定時在排除的字段前加 - 號,只寫字段名的是包含。

Model.find({},'age');
Model.find({},'-name');

對象形式指定時,1 是包含,0 是排除。

Model.find({}, { age: 1 });
Model.find({}, { name: 0 });

使用 select() 方法定義

Model.find().select('name age');
Model.find().select({ name: 0 });

參數三:options

// 三種方式實現
Model.find(filter,null,options)
Model.find(filter).setOptions(options)
Model.find(filter).<option>(xxx)

options 選項見官方文檔 Query.prototype.setOptions()

  • sort:按照排序規則根據所給的字段進行排序,值能夠是 asc, desc, ascending, descending, 1, 和 -1
  • limit:指定返回結果的最大數量
  • skip:指定要跳過的文檔數量
  • lean:返回普通的 js 對象,而不是 Mongoose Documents。建議不須要 mongoose 特殊處理就返給前端的數據都最好使用該方法轉成普通 js 對象。
// sort 兩種方式指定排序
Model.find().sort('age -name'); // 字符串有 - 表明 descending 降序
Model.find().sort({age:'asc', name:-1});

sortlimit 同時使用時,調用的順序並不重要,返回的數據都是先排序後限制數量。

// 效果同樣
Model.find().limit(2).sort('age');
Model.find().sort('age').limit(2);

參數四:callback

傳入

Mongoose 中全部傳入 callback 的查詢,其格式都是 callback(error, result) 這種形式。若是出錯,則 error 是出錯信息,resultnull;若是查詢成功,則 errornullresult 是查詢結果,查詢結果的結構形式是根據查詢方法的不一樣而有不一樣形式的。

find() 方法的查詢結果是數組,即便沒查詢到內容,也會返回 [] 空數組。

不傳

不傳入 callback 時,查詢方法返回的是一個 Query 實例,實例繼承了 Query 原型 上的全部方法,所以返回的實例能夠鏈式調用其它方法,從而組成查詢鏈。

let query = Model.find({ name: 'Dora' });

query.select('name age -_id');

查詢方法不傳入回調函數時,獲取查詢數據的方式有兩種:

1. exec()

使用 query 實例的 exec() 方法執行查詢,即在鏈式語法的最後統一經過傳入 callback 獲取查詢數據。

// 效果同樣
Model.find(
  { name: /Dora/, age: { $gte: 16, $lt: 18 } },
  'name age -_id',
  { limit: 2, sort: 'age' },
  (err,res)=>{
    if (err) return handleError(err);
    console.log(res);
  }
});

let query = Model.
  find({ name: /Dora/ }).
  where('age').gte(16).lt(18).
  select('name age -_id').
  limit(2).sort('age');

  query.exec((err, res)=> {
    if (err) return handleError(err);
    console.log(res);
  });

2. then()

使用 query 實例的 then() 方法將查詢鏈看成 promise 來處理。

query.then(
  (res) => {console.log(res)},
  (err) => {console.log(err)}
);

使用 async / await 獲取查詢結果。

let res = await query;
console.log(res);

findOne()

Model.findOne(conditions[, projection][, options][, callback])

conditions

若是查詢條件是 _id,建議使用 findById()

options 選項有限

並非全部 options 均可以用,所以鏈式調用 Query 原型上的方法時,也只能調用可用的方法。參考 Query.prototype.setOptions()

result 查詢結果

  • 返回數據的格式是 {} 對象形式。
  • 有多個數據知足查詢條件的,只返回第一條。
  • 查詢條件 conditions{}nullundefined,將任意返回一條數據。
  • 沒有符合查詢條件的數據,result 返回 null

findById()

Model.findById(id[, projection][, options][, callback])

id

Model.findById(id) 至關於 Model.findOne({ _id: id })

?? 摘自官方

不一樣之處在於處理 idundefined 時的狀況。 findOne({ _id: undefined }) 至關於 findOne({}),返回任意一條數據。而 findById(undefined) 至關於 findOne({ _id: null }),返回 null

測試結果爲 findOne({ _id: undefined }) 依舊返回 null。因此也多是 mongoose 版本的問題,可是即便數據返回正常,依然建議 _id 查詢使用 findById()

result 查詢結果

  • 返回數據的格式是 {} 對象形式。
  • idundefinednullresult 返回 null
  • 沒符合查詢條件的數據,result 返回 null
相關文章
相關標籤/搜索