mongodb 查询

 1.关于mongodb的思考

mongodb最大的特点就是能直接储存json字符串,而不用转化为关系型数据库的一个个字段,好处就是拓展字段很容易,坏处就是不能像关系型数据库一样不同表之间通过left join 等操作进行关联查询.

之前也思考过如果数据库存的是json对象,那么怎么根据条件查询想要的json呢?其实mongodb就可以解决,简单的find语法就可以筛选出符合条件的json对象,find({})一个空对象可以查询出所有对象,还是挺方便的,如果用关系型数据库来实现的话就需要把字段都转化成java对象进行过滤,但是mongodb可以直接在数据库层面完成这个操作,还是非常方便.虽然有思考过业务场景,但是没有工作中用不到,还是多少接触下mongodb,以后碰到了在深入学习.敬畏技术!

2. 根据条件查询数据

db.users.find({"birthday":"11"})可以查询出生日为11的用户

 

还是非常方便,不用转化成java对象,而且也比关系型数据库方便了许多.技术没有好坏,只是场景不同.

多条件下,可以传入多个字段

db.users.find({"birthday":"11","age": 11}) 同时查找年龄为11的用户;

3.  指定返回的键

用关系型数据库来说就是字段,可以指定返回的字段

db.users.find({"birthday":"11","age": 11},{"birthday":1}) 这里我只展示birthday字段,如果设置为0则不展示birthday字段. 

db.users.find({"birthday":"11","age": 11},{"birthday":1,"_id":0}) 如果加上 _id为0,则可以把默认的_id字段去除掉.

4.限制

 

查询有一个限制就是字段不能作为查询条件的值,比如:

 

db.users.find({"birthday":"this.age"}) 

 

我想把年龄的值作为参数传递给birthday查询条件,这样是无法实现的,会解析为 this.age字符串,查询参数必须是一个常量.

 

5.查询条件

5.1 查询条件

查询条件有 "$lt" "$lte" "$gt" "$gte" "$ne" 分别为 < ,<= ,> ,>= ,!=;

db.users.find({"age": {"$gt": 15, "$lt": 20}}) 这个代码的意思查询年龄大于15,小于20的用户,需要注意的是查询条件需要和字段类型一直,否则不会执行成功.

 5.2 $or

类似于sql语法中的 or 语句,只要一个条件符合就查询

db.users.find({"$or":[{"age":22}, {"name":"Bob"}]}) 查询姓名是Bob或者年龄是22的用户

5.3 $not

$not是元条件运算符,需要一个文档参数,意思是查询不符合not参数的文档

db.users.find({"age":{"$not":{"$mod": [5.1]}}}) 意思是查询年龄不是除以5后余数为1的用户.

5.4 null 

null可以单独作为查询条件

db.users.find({"age":null}) 这个语句会查询年龄为null的用户和没有age字段的用户,如果想查询只包含age字段的用户,可以加上$exists

db.users.find({"age":{"$eq":null, "$exists": true}})

5.5 正则表达式 $regex

不重复赘述了,基本上所有语言都支持正则表达式

db.users.find({"name":{"$regex": /joy/i}}) 可以查询到name为joy的用户,不区分大小写.

5.6 数组查询

5.6.1 $all

$all可以查询数组,比如有如下数组: db.food.insertOne({"fruit":["apple","banana","peach"]})

我们可以用$all查询想要的数据

db.food.find({"fruit":{"$all": ["apple"]}}) 我们可以查询到fruit数组中包含apple的数据.

也可以指定下标查找

db.food.find({"fruit.2":"peach"}) 可以查找fruit下标为2是peach的水果.

5.6.2 $size

根据数组的大小查找,不能和$lt $gt 同时使用

db.food.find({"fruit": {"$size": 3}}) 可以查找数组为3的数据.

如果想用大于小于进行比较的话,可以单独增加一个size字段进行比较.

5.6.3 $slice

执行返回数组的长度, find方法第一个参数是条件,第二个是返回格式,我们可以用$slice指定返回数组的大小.

db.food.find({"fruit":{"$all":["apple"]}}, {"fruit":{"$slice": 2}) 返回包含apple数组的文档,同时只返回前两个数据.

如果是负数的话则返回后两个.

$slice会返回所有键,只是限制了数组的长度.

5.6.4 $运算符返回匹配的元素

db.foot.find({"comments.name":"bob", {"comments.$" : 1}}) 会返回文档中第一个匹配的元素.

5.6.5 利用$elemMatch 限制过滤条件只过滤数组

如果单纯的进行 $lt $gt 比较数组和数字会造成数组不准确,我们加上$elemMatch来限制只判断数组

db.test.find({"x":{"$elemMatch":{"$lt" 20, "$gt": 5}}})会查找x数组小于20大于5的数组.

5.6.6查询内嵌文档

如果要查找内嵌文档,可以用 .  点表示法来查找.

db.people.find({"name.first":"Joe"}) 用来查找姓为Joe的人员.如果直接db.people.find({"name":{"first":"Joe"}})则不行,这种方式是精确匹配,少个字段都无法查找.

如果想查询数组中的元素,就是5.6.5中提到的,用$elemMatch限制只查找数组.

5.7 $where查询

$where可以执行js脚本,比如:

db.test.find({"$where": function () {   // 自定义条件   return true;} })

只有当方法里面的条件为true的时候,才返回数据.

但是$where查询执行比较慢,不建议使用.

5.8 游标

 类似于java的遍历器iterator,通过find获取一个游标,可以进行遍历

var cursor = db.collections.find();

while(cursor.hasNext()){

  var obj = cursor.next();

  print(obj);

}

没什么好说的,基本操作.

注意: 游标遍历完会自动销毁,释放内存,如果没有遍历完,10分钟后mongodb也会销毁.

5.9 limit,skip,sort

limit限制查询数量

db.collections.find().limit(3) 只会查找三条数据.

skip 根据参数忽略查询结果

db.collections.find().limit(3)  会忽略前三条数据

sort排序

db.collections.find().sort({x:1}) 按照x字段正序或者倒序排列.

类似于其他语言的流式操作,可以结合使用

db.collections.find().limit(3) .sort({x:1})过滤前三个在排序.

注意: 分页等操作尽量不使用skip和limit操作,这样做效率比较低,可以使用 $lt先过滤一部分,在用limit筛选.

 

posted @ 2022-06-24 22:03  随意的马蒂洛克  阅读(1651)  评论(0编辑  收藏  举报