MongoDB学习笔记三(查询)
一、比较查询运算符
$eq 相等
①等于指定值
等价于:
查询结果:
②嵌入式文档中的字段等于一个值
查询结果:
③数组元素等于一个值
执行结果:
④等于数组值
执行结果:
$gt大于
执行结果:
$gte大于等于
执行结果:
$lt、$lte同理。
$in 在...中
使用$in运算符匹配值
执行结果:
使用$in运算符匹配数组中的值
执行结果:
$ne不等于,用法等同于$in
$nin 不在...中,用法等同于$in
二、逻辑查询运算符
$and
语法:{ $and: [ { <expression1> }, { <expression2> } , ... , { <expressionN> } ] }
$and 对一个或多个表达式(、等)AND的数组 执行逻辑运算,并选择满足所有表达式的文档。
示例:
也可隐式的如下操作:
$not
语法:{ field: { $not: { <operator-expression> } } }
$nor
语法:{ $nor: [ { <expression1> }, { <expression2> }, ... { <expressionN> } ] }
$nor对一个或多个表达式的数组执行逻辑运算。
$or
语法:{ $or: [ { <expression1> }, { <expression2> }, ... , { <expressionN> } ] }
$or对一个或多个表达式的数组执行逻辑运算。
三、元素查询运算符
$exists
语法:{ field: { $exists: <boolean> } }
<boolean>是真的,$exists匹配包含该字段的文档,包括字段值为 的文档 null。如果<boolean>为 false,则查询仅返回不包含该字段的文档
{ a: 5, b: 5, c: null }
{ a: 3, b: null, c: 8 }
{ a: null, b: 3, c: 9 }
{ a: 1, b: 2, c: 3 }
{ a: 2, c: 5 }
{ a: 3, b: 2 }
{ a: 4 }
{ b: 2, c: 4 }
{ b: 2 }
{ c: 6 }
db.records.find( { a: { $exists: true } } )
执行结果:
{ a: 5, b: 5, c: null }
{ a: 3, b: null, c: 8 }
{ a: null, b: 3, c: 9 }
{ a: 1, b: 2, c: 3 }
{ a: 2, c: 5 }
{ a: 3, b: 2 }
{ a: 4 }
db.records.find( { a: { $exists: flase } } )
执行结果:
{ a: 2, c: 5 }
{ a: 4 }
{ c: 6 }
四、计算查询
$expr
语法:{ $expr: { <expression> } }
可以构建查询表达式,可以使用let变量比较字段。
示例1:
{ "_id" : 1, "category" : "food", "budget": 400, "spent": 450 }
{ "_id" : 2, "category" : "drinks", "budget": 100, "spent": 150 }
{ "_id" : 3, "category" : "clothes", "budget": 100, "spent": 50 }
{ "_id" : 4, "category" : "misc", "budget": 500, "spent": 300 }
{ "_id" : 5, "category" : "travel", "budget": 200, "spent": 650 }
查找金额spent超过的文件budget:
db.monthlyBudget.find( { $expr: { $gt: [ "$spent" , "$budget" ] } } )
返回结果:
{ "_id" : 1, "category" : "food", "budget" : 400, "spent" : 450 }
{ "_id" : 2, "category" : "drinks", "budget" : 100, "spent" : 150 }
{ "_id" : 5, "category" : "travel", "budget" : 200, "spent" : 650 }
示例2:
db.supplies.insertMany([
{ "_id" : 1, "item" : "binder", "qty" : NumberInt("100"), "price" : NumberDecimal("12") },
{ "_id" : 2, "item" : "notebook", "qty" : NumberInt("200"), "price" : NumberDecimal("8") },
{ "_id" : 3, "item" : "pencil", "qty" : NumberInt("50"), "price" : NumberDecimal("6") },
{ "_id" : 4, "item" : "eraser", "qty" : NumberInt("150"), "price" : NumberDecimal("3") },
{ "_id" : 5, "item" : "legal pad", "qty" : NumberInt("42"), "price" : NumberDecimal("10") }
])
要求:假设对于下个月即将进行的促销活动,您想要打折的价格是:
如果qty大于或等于 100,则折扣价为 的 0.5 price。
如果qty小于 100,则折扣价为 的 0.75 price。
在应用折扣之前,您想知道 supplies集合中哪些商品的折扣价低于5。
let discountedPrice = {
$cond: {
if: { $gte: ["$qty", 100] },
then: { $multiply: ["$price", NumberDecimal("0.50")] },
else: { $multiply: ["$price", NumberDecimal("0.75")] }
}
};
db.supplies.find( { $expr: { $lt:[ discountedPrice, NumberDecimal("5") ] } });
执行结果:
{ "_id" : 2, "item" : "notebook", "qty": 200 , "price": NumberDecimal("8") }
{ "_id" : 3, "item" : "pencil", "qty": 50 , "price": NumberDecimal("6") }
{ "_id" : 4, "item" : "eraser", "qty": 150 , "price": NumberDecimal("3") }
$mod 取余
语法:{ field: { $mod: [ divisor, remainder ] } }
示例:
db.inventory.insertMany( [
{ "_id" : 1, "item" : "abc123", "qty" : 0 },
{ "_id" : 2, "item" : "xyz123", "qty" : 5 },
{ "_id" : 3, "item" : "ijk123", "qty" : 12 }
] )
db.inventory.find({qty:{$mod:{4,0}}})
执行结果:
{ "_id" : 1, "item" : "abc123", "qty" : 0 },
{ "_id" : 3, "item" : "ijk123", "qty" : 12 }
注:语法中的division如果是小数,如4.4, 4.5, 4.9,取余时直接除数直接按照4进行取余
即:
db.inventory.find({qty:{$mod:{4.99,0}}})
执行结果:
{ "_id" : 1, "item" : "abc123", "qty" : 0 },
{ "_id" : 3, "item" : "ijk123", "qty" : 12 }
$regex 正则表达式
语法:
{ <field>: { $regex: /pattern/, $options: '<options>' } }
{ <field>: { $regex: 'pattern', $options: '<options>' } }
{ <field>: { $regex: /pattern/<options> } }
options:
i 不区分大小匹配
m 对于包含锚点(即^开始、 $结束)的模式,在每行的开头或结尾匹配具有多行值的字符串。如果没有此选项,这些锚点将在字符串的开头或结尾匹配
x 忽略所有空白字符,包括未转义的井号/井号 ( #) 字符和下一个换行符
s 允许点字符(即.)匹配所有字符,包括换行符
示例:
db.products.insertMany( [
{ _id: 100, sku: "abc123", description: "Single line description." },
{ _id: 101, sku: "abc789", description: "First line\nSecond line" },
{ _id: 102, sku: "xyz456", description: "Many spaces before line" },
{ _id: 103, sku: "xyz789", description: "Multiple\nline description" },
{ _id: 104, sku: "Abc789", description: "SKU starts with A" }
] )
^ 以...开头
$ 以...结尾
①进行like匹配
db.products.find( { sku: { $regex: /789$/ } } )
类似于sql like语句,如 where sku like '%789'
执行结果:
[
{ _id: 101, sku: 'abc789', description: 'First line\nSecond line' },
{ _id: 103, sku: 'xyz789', description: 'Multiple\nline description' },
{ _id: 104, sku: 'Abc789', description: 'SKU starts with A' }
]
②执行不区分大小写的正则表达式匹配
db.products.find( { sku: { $regex: /^ABC/i } } )
执行结果:
[
{ _id: 100, sku: 'abc123', description: 'Single line description.' },
{ _id: 101, sku: 'abc789', description: 'First line\nSecond line' },
{ _id: 104, sku: 'Abc789', description: 'SKU starts with A' }
]
③以指定模式开始的多行匹配
db.products.find( { description: { $regex: /^S/, $options: 'm' } } )
执行结果:
[
{ _id: 100, sku: 'abc123', description: 'Single line description.' },
{ _id: 101, sku: 'abc789', description: 'First line\nSecond line' },
{ _id: 104, sku: 'Abc789', description: 'SKU starts with A' }
]
如果没有m选项
db.products.find( { description: { $regex: /^S/} } )
执行结果:
[
{ _id: 100, sku: 'abc123', description: 'Single line description.' },
{ _id: 104, sku: 'Abc789', description: 'SKU starts with A' }
]
db.products.find( { description: { $regex: /S/ } } )
执行结果:
[
{ _id: 100, sku: 'abc123', description: 'Single line description.' },
{ _id: 101, sku: 'abc789', description: 'First line\nSecond line' },
{ _id: 104, sku: 'Abc789', description: 'SKU starts with A' }
]
④使用.点字符匹配新行
以下示例使用s允许点字符(即.)匹配所有字符(包括换行符)的选项以及 i执行不区分大小写的匹配的选项:
db.products.find( { description: { $regex: /m.*line/, $options: 'si' } } )
执行结果:
[
{ _id: 102, sku: 'xyz456', description: 'Many spaces before line' },
{ _id: 103, sku: 'xyz789', description: 'Multiple\nline description' }
]
如果没有s选项,执行结果:
[
{ _id: 102, sku: 'xyz456', description: 'Many spaces before line' }
]
⑤忽略模式中的空白
以下示例使用x忽略空格和注释的选项,在匹配模式中以#和 结尾:\n
var pattern = "abc #category code\n123 #item number"
db.products.find( { sku: { $regex: pattern, $options: "x" } } )
执行结果:
[
{ _id: 100, sku: 'abc123', description: 'Single line description.' }
]
⑥使用正则表达式匹配字符串中的大小写
db.products.find( { sku: { $regex: "(?i)a(?-i)bc" } } )
执行结果:
[
{ _id: 100, sku: 'abc123', description: 'Single line description.' },
{ _id: 101, sku: 'abc789', description: 'First line\nSecond line' },
{ _id: 104, sku: 'Abc789', description: 'SKU starts with A' }
]