MongoDB学习笔记五—查询上
数据准备
{ "goods_id" : , "goods_name" : "KD876", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : "", "goods_name" : "诺基亚N85原装充电器", "createTime" : ISODate("2016-09-11T00:00:00Z") }
{ "goods_id" : , "goods_name" : "诺基亚原装5800耳机", "createTime" : ISODate("2016-10-09T00:00:00Z") }
{ "goods_id" : , "goods_name" : "索爱原装M2卡读卡器", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "胜创KINGMAX内存卡", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "诺基亚N85", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "飞利浦9@9v", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "诺基亚E66", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : "", "goods_name" : "索爱C702c", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "索爱C702c", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "摩托罗拉A810", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "诺基亚5320", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "诺基亚5800XM", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : "", "goods_name" : "摩托罗拉A810", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "恒基伟业G101", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "夏新N7", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "夏新T5", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "三星SGH-F258", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "三星BC01", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "createTime" : ISODate("2015-10-01T00:00:00Z") }
find
find的第一个参数决定了要返回哪些文档,用于指定查询条件。要不指定查询文档,默认就是{},指定多个键/值对,相当于sql的and。第二个参数来指定想要的键(默认情况下,"_id"总是显示)。
查询条件
And查询
使用AND型查询时,应尽可能用最少的条件来限定结果的范围。
> db.product.find({"goods_id":"","goods_name":"诺基亚N85原装充电器"},{"_id":})
{ "goods_id" : "", "goods_name" : "诺基亚N85原装充电器", "createTime" : ISODate("2016-09-11T00:00:00Z") }
当然也可以这样(纯属闲得蛋疼):
> db.product.find({"$and":[{"goods_id":"","goods_name":"诺基亚N85原装充电器"}]},{"_id":})
{ "goods_id" : "", "goods_name" : "诺基亚N85原装充电器", "createTime" : ISODate("2016-09-11T00:00:00Z") }
Or查询
方式一:$in、$nin
$in可以用来查询一个键的多个值,可以指定不同类型的条件和值。
$nin将返回与数组中所有条件都不匹配的文档。
$in是对单个键做OR查询。
> db.product.find({"goods_id":{"$in":["",,]}},{"_id":})
{ "goods_id" : "", "goods_name" : "诺基亚N85原装充电器", "createTime" : ISODate("2016-09-11T00:00:00Z") }
{ "goods_id" : , "goods_name" : "索爱原装M2卡读卡器", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "胜创KINGMAX内存卡", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
>
方式二:$or
$or更通用一些,可以在多个键中查询任意的给定值
使用$or时,第一个条件条件应尽可能匹配更多的文档,这样才是最为高效的。
> db.product.find({"$or":[{"goods_id":},{"goods_name":"夏新T5"},{"createTime":{"$lt":new Date("2016-01-01")}}]},{"_id":})
{ "goods_id" : , "goods_name" : "恒基伟业G101", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "夏新T5", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "createTime" : ISODate("2015-10-01T00:00:00Z") }
$lt、 $lte、 $gt、 $gte、$eq(貌似没什么用)、$ne
$lt、 $lte、 $gt、 $gte、$eq、$ne分别对应sql中的<、<= 、>、>=、=、!=。组合查找一个范围的值。
> db.product.find({"goods_id":{"$gte":,"$lt":}},{"_id":} )
{ "goods_id" : , "goods_name" : "诺基亚原装5800耳机", "createTime" : ISODate("2016-10-09T00:00:00Z") }
> start=new Date("01/01/2016")
ISODate("2015-12-31T16:00:00Z")
> db.product.find({"createTime":{"$lt":start}})//查询指定日期之前的数据
{ "_id" : ObjectId("585a65d9a847c6d3a3ee1da5"), "goods_id" : , "createTime" : ISODate("2015-10-01T00:00:00Z") }
限制
查询使用上有些限制。传递给数据库的查询文档的值必须是常量。也就是说不能引用文档中其他键的值。
db.product.find({"goods_id":this.goods_name}).pretty()
$mod
取模运算符,会将查询的值除以第一个给定值,若余数等于第二个给定的值则匹配成功。
> db.product.find({"goods_id":{"$mod":[,]}},{"_id":})
{ "goods_id" : , "goods_name" : "KD876", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "胜创KINGMAX内存卡", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "索爱C702c", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "恒基伟业G101", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
>
$not
$not是元条件句,即可以用在其他任何其他条件之上。查询和匹配的件相反的数据。
$not与正则表达式联合使用时极为有用,用来查找那些与特定模式不匹配的文档。
> db.product.find({"goods_id":{"$not":{"$mod":[,]}}},{"_id":})
{ "goods_id" : "", "goods_name" : "诺基亚N85原装充电器", "createTime" : ISODate("2016-09-11T00:00:00Z") }
{ "goods_id" : , "goods_name" : "诺基亚原装5800耳机", "createTime" : ISODate("2016-10-09T00:00:00Z") }
{ "goods_id" : , "goods_name" : "索爱原装M2卡读卡器", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "诺基亚N85", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "飞利浦9@9v", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "诺基亚E66", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : "", "goods_name" : "索爱C702c", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "摩托罗拉A810", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "诺基亚5320", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "诺基亚5800XM", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : "", "goods_name" : "摩托罗拉A810", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "夏新N7", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "夏新T5", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "三星SGH-F258", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "三星BC01", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "createTime" : ISODate("2015-10-01T00:00:00Z") }
条件语义
在查询中,$lt在内层文档,而在更新中$inc则是外层文档的键。
基本可以肯定:条件语句是内层文档的键,而修改器则是外层文档的键。
一个键可以有任意多个条件,但是一个键不能对应多个更新修改器。
有一些”元操作符”也位于外层文档中,比如$and、$or、$nor
查询优化器不会$and进行优化,这与其他操作符不相同。
特定类型的查询
null
null不仅会匹配某个键的值为null的文档,而且还会匹配不含这个键的文档。
如果仅想匹配键值为null的文档,既要检查该键的值是否为null,还要通过$exists条件判断键值已存在。
> db.product.update({"goods_id":},{"$set":{"goods_name":null}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.product.find({"goods_name":null},{"_id":})
{ "goods_id" : , "createTime" : ISODate("2015-10-01T00:00:00Z"), "goods_name" : null }
> db.product.find({"goods_no":{"$in":[null],"$exists":true}},{"_id":})
正则表达式
正则表达式能够灵活有效地匹配字符串,系统可以接收正则表达式标志i (忽略大小写),但不一定要有。
MongoDB可以为前缀型正则表达式(比如:/^joey/)查询创建索引,所以这种类型的查询会非常高效。
> db.product.find({"goods_name":/^三星/},{"_id":})
{ "goods_id" : , "goods_name" : "三星SGH-F258", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
{ "goods_id" : , "goods_name" : "三星BC01", "createTime" : ISODate("2016-12-21T11:19:39.010Z") }
正则表达式也可以匹配自身。
> db.product.find({"goods_name":/baz/},{"_id":})
{ "goods_id" : , "goods_name" : /baz/, "createTime" : ISODate("2016-10-09T00:00:00Z") }
查询数组
查询数组元素与查询标量值是一样的。
> db.product.update({"goods_id":""},{"$push":{"goods_type":{"$each":["华为", "乐视", "小米"]}}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.product.find({"goods_type":"小米"},{"_id":})
{ "goods_id" : "", "goods_name" : "索爱C702c", "createTime" : ISODate("2016-12-21T11:19:39.010Z"), "goods_type" : [ "华为", "乐视", "小米" ] }
$all
通过多个元素来匹配数组,这样就会匹配一组元素。
> db.product.update({"goods_id":},{"$push":{"goods_type":{"$each":["三星", "苹果", "努比亚"]}}})> db.product.update({"goods_id":},{"$push":{"goods_type":{"$each":["华为", "苹果", "魅族"]}}})
> db.product.find({"goods_type":{"$all":["苹果","华为"]}},{"_id":})
{ "goods_id" : , "goods_name" : "夏新T5", "createTime" : ISODate("2016-12-21T11:19:39.010Z"), "goods_type" : [ "华为", "苹果", "魅族" ] }
当然也可以使用整个数组进行精确匹配。但是,精确匹配必须一模一样的才查的出来,比如顺序,个数都得一样。
> db.product.find({"goods_type":["华为","苹果","魅族"]},{"_id":})
{ "goods_id" : , "goods_name" : "夏新T5", "createTime" : ISODate("2016-12-21T11:19:39.010Z"), "goods_type" : [ "华为", "苹果", "魅族" ] }
查找特定位置的元素
要想查询数组特定位置的元素,需使用key.index语法指定下标,数组下标都是从0开始的。
> db.product.find({"goods_type.1":"苹果"},{"_id":})
{ "goods_id" : , "goods_name" : "夏新T5", "createTime" : ISODate("2016-12-21T11:19:39.010Z"), "goods_type" : [ "华为", "苹果", "魅族" ] }
{ "goods_id" : , "goods_name" : "三星BC01", "createTime" : ISODate("2016-12-21T11:19:39.010Z"), "goods_type" : [ "三星", "苹果", "努比亚" ] }
>
$size
$size查询特定长度的数组
> db.product.find({"goods_type":{"$size":}},{"_id":})
{ "goods_id" : "", "goods_name" : "索爱C702c", "createTime" : ISODate("2016-12-21T11:19:39.010Z"), "goods_type" : [ "华为", "乐视", "小米" ] }
{ "goods_id" : , "goods_name" : "夏新T5", "createTime" : ISODate("2016-12-21T11:19:39.010Z"), "goods_type" : [ "华为", "苹果", "魅族" ] }
{ "goods_id" : , "goods_name" : "三星BC01", "createTime" : ISODate("2016-12-21T11:19:39.010Z"), "goods_type" : [ "三星", "苹果", "努比亚" ] }
>
$slice
$slice操作符可以返回某个键匹配的数组元素的一个子集。这个操作符是用来获取数组的前几个或者后几个元素,对整个数据进行过滤没有作用(比如: db.product.find({},{"goods_type":{"$slice":}}) 会返回文档的所有数据)
> db.product.find({"goods_type":{"$size":}},{"goods_type":{"$slice":-},"_id":})
{ "goods_id" : "", "goods_name" : "索爱C702c", "createTime" : ISODate("2016-12-21T11:19:39.010Z"), "goods_type" : [ "乐视", "小米" ] }
{ "goods_id" : , "goods_name" : "夏新T5", "createTime" : ISODate("2016-12-21T11:19:39.010Z"), "goods_type" : [ "苹果", "魅族" ] }
{ "goods_id" : , "goods_name" : "三星BC01", "createTime" : ISODate("2016-12-21T11:19:39.010Z"), "goods_type" : [ "苹果", "努比亚" ] }
> db.product.find({"goods_type":{"$size":}},{"goods_type":{"$slice":},"_id":})
{ "goods_id" : "", "goods_name" : "索爱C702c", "createTime" : ISODate("2016-12-21T11:19:39.010Z"), "goods_type" : [ "华为", "乐视" ] }
{ "goods_id" : , "goods_name" : "夏新T5", "createTime" : ISODate("2016-12-21T11:19:39.010Z"), "goods_type" : [ "华为", "苹果" ] }
{ "goods_id" : , "goods_name" : "三星BC01", "createTime" : ISODate("2016-12-21T11:19:39.010Z"), "goods_type" : [ "三星", "苹果" ] }
>
$slice也可以指定偏移值以及希望返回的元素数量,来返回元素集合中间位置的某些结果。
> db.product.find({"goods_type":{"$size":}},{"goods_type":{"$slice":[,]},"_id":})//跳过1个,取1个
{ "goods_id" : "", "goods_name" : "索爱C702c", "createTime" : ISODate("2016-12-21T11:19:39.010Z"), "goods_type" : [ "乐视" ] }
{ "goods_id" : , "goods_name" : "夏新T5", "createTime" : ISODate("2016-12-21T11:19:39.010Z"), "goods_type" : [ "苹果" ] }
{ "goods_id" : , "goods_name" : "三星BC01", "createTime" : ISODate("2016-12-21T11:19:39.010Z"), "goods_type" : [ "苹果" ] }
返回一个匹配的数组元素
$ 返回与查询条件相匹配的任意一个数组元素。只会返回第一个匹配的文档。
> db.blog.find({"comments.votes":}).pretty()
{
"_id" : ObjectId("585694e4c5b0525a48a441b5"),
"content" : "...",
"comments" : [
{
"comment" : "good post",
"author" : "jim",
"votes" :
},
{
"comment" : "i thought it was too short",
"author" : "claire",
"votes" :
},
{
"comment" : "free watches",
"author" : "alice",
"votes" :
}
]
}
>
> db.blog.find({"comments.votes":},{"comments.$":}).pretty()
{
"_id" : ObjectId("585694e4c5b0525a48a441b5"),
"comments" : [
{
"comment" : "i thought it was too short",
"author" : "claire",
"votes" :
}
]
}
数组和范围查询的相互作用
文档中的标量(非数组元素)必须与查询条件中的每一条语句相匹配。比如,如果使用 {"$gt":,"$lt":} 进行查询,只会匹配x键的值大于10并且小于20的文档。
但是,假如某个文档的x字段是一个数组,如果x键的某一个元素与查询条件得到任意一条语句相匹配,那么这个文档也会被返回。
{ "_id" : ObjectId("585d404b53fe663a4c5c202e"), "x" : }
{ "_id" : ObjectId("585d404b53fe663a4c5c202f"), "x" : }
{ "_id" : ObjectId("585d404b53fe663a4c5c2030"), "x" : }
{ "_id" : ObjectId("585d404b53fe663a4c5c2031"), "x" : [ , ] }
> db.foo.find({"x":{"$gt":,"$lt":}})
{ "_id" : ObjectId("585d404b53fe663a4c5c202f"), "x" : }
{ "_id" : ObjectId("585d404b53fe663a4c5c2031"), "x" : [ , ] }
上述方式对数组使用范围查询没有用:范围会匹配任意多个元素数组。有几种方式可以得到预期的结果。
方式1:$elemMatch
$elemMatch要求MongoDB同时使用查询条件中的两个语句与一个数组元素进行比较。但是,它不会匹配非数组元素。
> db.foo.find({"x":{"$elemMatch":{"$gt":,"$lt":}}})
>
方式2:使用min()和max()
如果当前查询的字段上创建过索引,可以使用min()和max()将查询条件遍历的索引范围限制为”$gt”和”$lt”的值。而且,必须为这个索引的所有字段指定min()和max().
> db.foo.find({"x":{"$gt":,"$lt":}}).min({"x":}).max({"x":})
MongoDB学习笔记五—查询上的更多相关文章
- Mongodb学习笔记五(C#操作mongodb)
mongodb c# driver(驱动)介绍 目前基于C#的mongodb驱动有两种,分别是官方驱动(下载地址)和samus驱动(下载地址). 本次我们只演示官方驱动的使用方法. 官方驱动文档查看 ...
- MongoDB学习笔记六—查询下
查询内嵌文档 数据准备 > db.blog.find().pretty() { "_id" : ObjectId("585694e4c5b0525a48a441b5 ...
- MongoDB学习笔记五:聚合
『count』count是最简单的聚合工具,返回集合中的文档数量:> db.foo.count()0> db.foo.insert({"x" : 1})> db. ...
- python学习笔记五 模块上(基础篇)
模块学习 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要 ...
- MongoDB学习笔记(五) MongoDB文件存取操作
由于MongoDB的文档结构为BJSON格式(BJSON全称:Binary JSON),而BJSON格式本身就支持保存二进制格式的数据,因此可以把文件的二进制格式的数据直接保存到MongoDB的文档结 ...
- mongodb 学习笔记 3 --- 查询
在mongodb的查询中可以通过使用如下操作符进行深度查询 1.条件操作符 $gt $gte : > >= {"age":{"$gt":18 ...
- MongoDB 学习笔记之 查询表达式
查询表达式: db.stu.find().count() db.stu.find({name: 'Sky'}) db.stu.find({age: {$ne: 20}},{name: 1, age: ...
- MongoDB学习笔记(转)
MongoDB学习笔记(一) MongoDB介绍及安装MongoDB学习笔记(二) 通过samus驱动实现基本数据操作MongoDB学习笔记(三) 在MVC模式下通过Jqgrid表格操作MongoDB ...
- 【转】MongoDB学习笔记(查询)
原文地址 MongoDB学习笔记(查询) 基本查询: 构造查询数据. > db.test.findOne() { "_id" : ObjectId("4fd58ec ...
随机推荐
- iOS可视化动态绘制连通图
上篇博客<iOS可视化动态绘制八种排序过程>可视化了一下一些排序的过程,本篇博客就来聊聊图的东西.在之前的博客中详细的讲过图的相关内容,比如<图的物理存储结构与深搜.广搜>.当 ...
- Akka.net路径里的user
因为经常买双色球,嫌每次对彩票号麻烦,于是休息的时候做了个双色球兑奖的小程序,做完了发现业务还挺复杂的,于是改DDD重做设计,拆分服务,各种折腾...,不过这和本随笔没多大关系,等差不多了再总结一下, ...
- SQL Server2014 SP2新增的数据库克隆功能
SQL Server2014 SP2新增的数据库克隆功能 创建测试库 --创建测试数据库 create database testtest use testtest go --创建表 )) --插入数 ...
- python程序生成平均脸
简介 项目代码https://github.com/LiuRoy/pokerface 原文链接http://www.cnblogs.com/lrysjtu/p/5492547.html 写这个项目的本 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(持续更新中...)
开发工具:VS2015(2012以上)+SQL2008R2以上数据库 您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB 升级后界面效果如下: 任务调度系统界面 http: ...
- 基于netty http协议栈的轻量级流程控制组件的实现
今儿个是冬至,所谓“冬大过年”,公司也应景五点钟就放大伙儿回家吃饺子喝羊肉汤了,而我本着极高的职业素养依然坚持留在公司(实则因为没饺子吃没羊肉汤喝,只能呆公司吃食堂……).趁着这一个多小时的时间,想跟 ...
- CSS 3 学习——渐变
通过CSS渐变创建的是一个没有固定比例和固定尺寸的<image>类型,也就是说是一张图片,这张图片的尺寸由所应用的元素的相关信息决定.凡是支持图片类型的CSS属性都可以设置渐变,而支持颜色 ...
- EC笔记:第4部分:22、所有成员都应该是private的
EC笔记:第4部分:22.所有成员都应该是private的 更简单的访问 用户不用记得什么时候该带上括号,什么时候不用带上括号(因为很确定的就要带上括号) 访问限制 对于public的成员变量,我们可 ...
- 怎样在Dos里切换盘符
一:在Dos里切换盘符 a:在电脑左下角右击显示图片;(我用的是win10系统,其他系统类似) b:点击运行,输入cmd; c:点击确定: d:输入盘符:(如f:) 或F: 只写字母,不写分号是不行的 ...
- 马哥linux运维初级+中级+高级 视频教程 教学视频 全套下载(近50G)
马哥linux运维初级+中级+高级 视频教程 教学视频 全套下载(近50G)目录详情:18_02_ssl协议.openssl及创建私有CA18_03_OpenSSH服务及其相关应用09_01_磁盘及文 ...