MongoDB-查询

2018-11-13  本文已影响12人  许先森的许

任何数据库中查询都是最麻烦的,在MongoDB中对于查询的支持非常到位,有关系运算,逻辑运算,数组运算等等
首先对于数据的操作核心语法:”db.集合名称.find({查询条件} , {设置显示的字段})“

db.dept.findOne()
输出:{
"_id" : ObjectId("5be8eab516d1fcb72bc0dd34"),
"deptno" : 10,
"dname" : "xc",
"loc" : "北京"
}
db.infos.find({'url':'www.hh.cn'})
输出:{ "_id" : ObjectId("5be917a716d1fcb72bc0dd3b"), "url" : "www.hh.cn" }

对于设置的显示字段严格来讲就称为数据的投影操作,(从一条数据的全部字段中拿出部分想要显示的字段来显示出来,就叫投影操作)如果不需要显示的字段设置”0“,而需要显示的设置为‘1’:
比如不想要显示_id:

db.infos.find({'url':'www.hh.cn'},{'_id':0})
或者:
db.infos.find({'url':'www.hh.cn'},{'_id':0,'url':1})

不部分情况下这种投影操作的意义不大。同时对于数据的查询也可以使用‘pretty()’函数进行漂亮的显示。数据列多的时候一定可以看出漂亮的显示。

db.students.find({'name':'张三'}).pretty()

{
    "_id" : ObjectId("5be9271d16d1fcb72bc0dd41"),
    "name" : "张三",
    "sex" : "男",
    "age" : 19,
    "score" : 89,
    "address" : "西湖区"
}

查询年龄大于19的数据:

db.students.find({'age':{'$gt':19}})
{ "_id" : ObjectId("5be9274916d1fcb72bc0dd42"), "name" : "李思", "sex" : "男", "age" : 20, "score" : 69, "address" : "拱墅区" }
{ "_id" : ObjectId("5be927af16d1fcb72bc0dd45"), "name" : "刘琦", "sex" : "女", "age" : 21, "score" : 0, "address" : "上城区" }
查询姓名不等于王五,同时年龄小于19的数据:
db.students.find({'name':{'$ne':'王五'},'age':{'$lt':19}})
{ "_id" : ObjectId("5be9278a16d1fcb72bc0dd44"), "name" : "赵柳", "sex" : "女", "age" : 17, "score" : 66, "address" : "余杭区" }

逻辑运算查询:
与($and)、或($or)、非($not或者$nor)

查询年龄在19~20岁的数据:
db.students.find({'age':{'$gte':19,'$lte':20}})
{ "_id" : ObjectId("5be9271d16d1fcb72bc0dd41"), "name" : "张三", "sex" : "男", "age" : 19, "score" : 89, "address" : "西湖区" }
{ "_id" : ObjectId("5be9274916d1fcb72bc0dd42"), "name" : "李思", "sex" : "男", "age" : 20, "score" : 69, "address" : "拱墅区" }

And比较容易,只需要用逗号分隔若干个条件即可。

查询年龄大于19或者成绩大于90分的数据:
db.students.find({'$or':[{'age':{'$gt':19}},{'socre':{'$gt':90}}]})
{ "_id" : ObjectId("5be9274916d1fcb72bc0dd42"), "name" : "李思", "sex" : "男", "age" : 20, "score" : 69, "address" : "拱墅区" }
{ "_id" : ObjectId("5be927af16d1fcb72bc0dd45"), "name" : "刘琦", "sex" : "女", "age" : 21, "score" : 0, "address" : "上城区" }
上面用到了”或“,也可以进行”或“的求反:
db.students.find({'$nor':[{'age':{'$gt':19}},{'socre':{'$gt':90}}]})
{ "_id" : ObjectId("5be9271d16d1fcb72bc0dd41"), "name" : "张三", "sex" : "男", "age" : 19, "score" : 89, "address" : "西湖区" }
{ "_id" : ObjectId("5be9277416d1fcb72bc0dd43"), "name" : "王五", "sex" : "女", "age" : 18, "score" : 100, "address" : "余杭区" }
{ "_id" : ObjectId("5be9278a16d1fcb72bc0dd44"), "name" : "赵柳", "sex" : "女", "age" : 17, "score" : 66, "address" : "余杭区" }

注意,使用或的时候要用到数组结构。

求模运算:
模的运算使用”$mod“来完成,语法”{$mod:[数字,余数]}“:

db.students.find({'age':{'$mod':[20,0]}})
{ "_id" : ObjectId("5be9274916d1fcb72bc0dd42"), "name" : "李思", "sex" : "男", "age" : 20, "score" : 69, "address" : "拱墅区" }
db.students.find({'age':{'$mod':[20,1]}})
{ "_id" : ObjectId("5be927af16d1fcb72bc0dd45"), "name" : "刘琦", "sex" : "女", "age" : 21, "score" : 0, "address" : "上城区" }

范围查询:
只要是数据库必须存在”$in“(在范围之中)、”$nin“(不在范围之中)
查询姓名是张三王五李思的信息:

db.students.find({'name':{'$in':['张三','李思','王五']}})
{ "_id" : ObjectId("5be9271d16d1fcb72bc0dd41"), "name" : "张三", "sex" : "男", "age" : 19, "score" : 89, "address" : "西湖区" }
{ "_id" : ObjectId("5be9274916d1fcb72bc0dd42"), "name" : "李思", "sex" : "男", "age" : 20, "score" : 69, "address" : "拱墅区" }
{ "_id" : ObjectId("5be9277416d1fcb72bc0dd43"), "name" : "王五", "sex" : "女", "age" : 18, "score" : 100, "address" : "余杭区" }

不在上面范围之内:

db.students.find({'name':{'$nin':['张三','李思','王五']}})
{ "_id" : ObjectId("5be9278a16d1fcb72bc0dd44"), "name" : "赵柳", "sex" : "女", "age" : 17, "score" : 66, "address" : "余杭区" }
{ "_id" : ObjectId("5be927af16d1fcb72bc0dd45"), "name" : "刘琦", "sex" : "女", "age" : 21, "score" : 0, "address" : "上城区" }

范围的操作也需要用到数组结构。

数组查询:
因为MongoDB是支持数组保存的,所以也需要针对数组的查询。可以使用几个运算符:$all、$size、$slice

db.students.insert({'name':'测试-A','course':['语文','数学','英语']})
WriteResult({ "nInserted" : 1 })
db.students.insert({'name':'测试-B','course':['语文','数学']})
WriteResult({ "nInserted" : 1 })
db.students.insert({'name':'测试-C','course':['语文','数学','英语','科学']})
WriteResult({ "nInserted" : 1 })
db.students.find()
{ "_id" : ObjectId("5be9271d16d1fcb72bc0dd41"), "name" : "张三", "sex" : "男", "age" : 19, "score" : 89, "address" : "西湖区" }
{ "_id" : ObjectId("5be9274916d1fcb72bc0dd42"), "name" : "李思", "sex" : "男", "age" : 20, "score" : 69, "address" : "拱墅区" }
{ "_id" : ObjectId("5be9277416d1fcb72bc0dd43"), "name" : "王五", "sex" : "女", "age" : 18, "score" : 100, "address" : "余杭区" }
{ "_id" : ObjectId("5be9278a16d1fcb72bc0dd44"), "name" : "赵柳", "sex" : "女", "age" : 17, "score" : 66, "address" : "余杭区" }
{ "_id" : ObjectId("5be927af16d1fcb72bc0dd45"), "name" : "刘琦", "sex" : "女", "age" : 21, "score" : 0, "address" : "上城区" }
{ "_id" : ObjectId("5be93fb416d1fcb72bc0dd46"), "name" : "测试-A", "course" : [ "语文", "数学", "英语" ] }
{ "_id" : ObjectId("5be93fc016d1fcb72bc0dd47"), "name" : "测试-B", "course" : [ "语文", "数学" ] }
{ "_id" : ObjectId("5be93fd616d1fcb72bc0dd48"), "name" : "测试-C", "course" : [ "语文", "数学", "英语", "科学" ] }
{ "_id" : ObjectId("5bea316f16d1fcb72bc0dd49"), "name" : "测试-D", "course" : [ "数学", "英语", "科学" ] }

db.students.find({'course':{'$all':['语文','数学']}})
{ "_id" : ObjectId("5be93fb416d1fcb72bc0dd46"), "name" : "测试-A", "course" : [ "语文", "数学", "英语" ] }
{ "_id" : ObjectId("5be93fc016d1fcb72bc0dd47"), "name" : "测试-B", "course" : [ "语文", "数学" ] }
{ "_id" : ObjectId("5be93fd616d1fcb72bc0dd48"), "name" : "测试-C", "course" : [ "语文", "数学", "英语", "科学" ] }

db.students.find({'address':{'$all':['拱墅区']}})
{ "_id" : ObjectId("5be9274916d1fcb72bc0dd42"), "name" : "李思", "sex" : "男", "age" : 20, "score" : 69, "address" : "拱墅区" }
db.students.find({'address':'拱墅区'})
{ "_id" : ObjectId("5be9274916d1fcb72bc0dd42"), "name" : "李思", "sex" : "男", "age" : 20, "score" : 69, "address" : "拱墅区" }

db.students.find({'course.1':'英语'})
{ "_id" : ObjectId("5bea316f16d1fcb72bc0dd49"), "name" : "测试-D", "course" : [ "数学", "英语", "科学" ] }

使用“$size”来进行数量的控制:
例如查询出只参加四门课程的学生:

db.students.find({'course':{'$size':4}})
{ "_id" : ObjectId("5be93fd616d1fcb72bc0dd48"), "name" : "测试-C", "course" : [ "语文", "数学", "英语", "科学" ] }

现在有个问题:只要条件满足,数组的内容就全部显示出来了,如果不想要全部显示呢?

db.students.find({'name':'测试-C'},{'course':{'$slice':2}})
{ "_id" : ObjectId("5be93fd616d1fcb72bc0dd48"), "name" : "测试-C", "course" : [ "语文", "数学" ] }

如果想要控制取后两门,学过js语法的都知道用负号:

db.students.find({'name':'测试-C'},{'course':{'$slice':-2}})
{ "_id" : ObjectId("5be93fd616d1fcb72bc0dd48"), "name" : "测试-C", "course" : [ "英语", "科学" ] }

那么取中间两门课程:

db.students.find({'name':'测试-C'},{'course':{'$slice':[1,2]}})
{ "_id" : ObjectId("5be93fd616d1fcb72bc0dd48"), "name" : "测试-C", "course" : [ "数学", "英语" ] }

这里的1,2表示的是从1index开始返回,返回2count个元素。

{
    "_id" : ObjectId("5bea488e16d1fcb72bc0dd4a"),
    "name" : "王木木-A",
    "sex" : "男",
    "age" : 19,
    "score" : 89,
    "address" : "西湖区",
    "course" : [
        "语文",
        "数学"
    >],
    "parents" : [
        {
            "name" : "王木木-A-父亲",
            "age" : 55
        },
        {
            "name" : "王木木-A-母亲",
            "age" : 56
        }
    ]
}
{
    "_id" : ObjectId("5bea48ed16d1fcb72bc0dd4b"),
    "name" : "王木木-B",
    "sex" : "男",
    "age" : 19,
    "score" : 89,
    "address" : "西湖区",
    "course" : [
        "语文",
        "英语"
    ],
    "parents" : [
        {
            "name" : "王木木-B-父亲",
            "age" : 51
        },
        {
            "name" : "王木木-B-母亲",
            "age" : 53
        }
    ]
}

db.students.find({'parents':{'$elemMatch':{'age':51}}})
{ "_id" : ObjectId("5bea48ed16d1fcb72bc0dd4b"), "name" : "王木木-B", "sex" : "男", "age" : 19, "score" : 89, "address" : "西湖区", "course" : [ "语文", "英语" ], "parents" : [ { "name" : "王木木-B-父亲", "age" : 51 }, { "name" : "王木木-B-母亲", "age" : 53 } ] }

db.students.find({'parents':{'$exists':true}})
{ "_id" : ObjectId("5bea488e16d1fcb72bc0dd4a"), "name" : "王木木-A", "sex" : "男", "age" : 19, "score" : 89, "address" : "西湖区", "course" : [ "语文", "数学" ], "parents" : [ { "name" : "王木木-A-父亲", "age" : 55 }, { "name" : "王木木-A-母亲", "age" : 56 } ] }
{ "_id" : ObjectId("5bea48ed16d1fcb72bc0dd4b"), "name" : "王木木-B", "sex" : "男", "age" : 19, "score" : 89, "address" : "西湖区", "course" : [ "语文", "英语" ], "parents" : [ { "name" : "王木木-B-父亲", "age" : 51 }, { "name" : "王木木-B-母亲", "age" : 53 } ] }
db.students.find({'parents':{'$exists':false}})
{ "_id" : ObjectId("5be9271d16d1fcb72bc0dd41"), "name" : "张三", "sex" : "男", "age" : 19, "score" : 89, "address" : "西湖区" }
{ "_id" : ObjectId("5be9274916d1fcb72bc0dd42"), "name" : "李思", "sex" : "男", "age" : 20, "score" : 69, "address" : "拱墅区" }
{ "_id" : ObjectId("5be9277416d1fcb72bc0dd43"), "name" : "王五", "sex" : "女", "age" : 18, "score" : 100, "address" : "余杭区" }
{ "_id" : ObjectId("5be9278a16d1fcb72bc0dd44"), "name" : "赵柳", "sex" : "女", "age" : 17, "score" : 66, "address" : "余杭区" }
{ "_id" : ObjectId("5be927af16d1fcb72bc0dd45"), "name" : "刘琦", "sex" : "女", "age" : 21, "score" : 0, "address" : "上城区" }
{ "_id" : ObjectId("5be93fb416d1fcb72bc0dd46"), "name" : "测试-A", "course" : [ "语文", "数学", "英语" ] }
{ "_id" : ObjectId("5be93fc016d1fcb72bc0dd47"), "name" : "测试-B", "course" : [ "语文", "数学" ] }
{ "_id" : ObjectId("5be93fd616d1fcb72bc0dd48"), "name" : "测试-C", "course" : [ "语文", "数学", "英语", "科学" ] }
{ "_id" : ObjectId("5bea316f16d1fcb72bc0dd49"), "name" : "测试-D", "course" : [ "数学", "英语", "科学" ] }

可以利用这种查询来过滤操作。

*** 条件过滤:**
传统关系型数据库对于数据的筛选,首先想到的是where,MongoDB中也有“$where”:
例如查询出所有年龄大于19岁的数据:

db.students.find({'$where':'this.age>19'})
{ "_id" : ObjectId("5be9274916d1fcb72bc0dd42"), "name" : "李思", "sex" : "男", "age" : 20, "score" : 69, "address" : "拱墅区" }
{ "_id" : ObjectId("5be927af16d1fcb72bc0dd45"), "name" : "刘琦", "sex" : "女", "age" : 21, "score" : 0, "address" : "上城区" }
还可以更简化写法:
db.students.find('this.age>19')
{ "_id" : ObjectId("5be9274916d1fcb72bc0dd42"), "name" : "李思", "sex" : "男", "age" : 20, "score" : 69, "address" : "拱墅区" }
{ "_id" : ObjectId("5be927af16d1fcb72bc0dd45"), "name" : "刘琦", "sex" : "女", "age" : 21, "score" : 0, "address" : "上城区" }

可以看出对于where是可以简化的。但是这类操作是属于对于每一行信息进行判断,对于数据量大的情况并不方便使用。
上面代码严格来讲是属于编写一个操作函数。

db.students.find({'$and':[{'$where':'this.age>19'},{'$where':'this.age<21'}]})
{ "_id" : ObjectId("5be9274916d1fcb72bc0dd42"), "name" : "李思", "sex" : "男", "age" : 20, "score" : 69, "address" : "拱墅区" }

虽然这种形式可以实现数据查询,但是最大缺点是将在MGO数据库里面保存的BSON数据变为了JS的语法结构,这样的方式不方便实用数据库索引机制

db.students.find({'name':/测/})
{ "_id" : ObjectId("5be93fb416d1fcb72bc0dd46"), "name" : "测试-A", "course" : [ "语文", "数学", "英语" ] }
{ "_id" : ObjectId("5be93fc016d1fcb72bc0dd47"), "name" : "测试-B", "course" : [ "语文", "数学" ] }
{ "_id" : ObjectId("5be93fd616d1fcb72bc0dd48"), "name" : "测试-C", "course" : [ "语文", "数学", "英语", "科学" ] }
{ "_id" : ObjectId("5bea316f16d1fcb72bc0dd49"), "name" : "测试-D", "course" : [ "数学", "英语", "科学" ] }

完整写法:

db.students.find({'name':{'$regex':/测/}})
{ "_id" : ObjectId("5be93fb416d1fcb72bc0dd46"), "name" : "测试-A", "course" : [ "语文", "数学", "英语" ] }
{ "_id" : ObjectId("5be93fc016d1fcb72bc0dd47"), "name" : "测试-B", "course" : [ "语文", "数学" ] }
{ "_id" : ObjectId("5be93fd616d1fcb72bc0dd48"), "name" : "测试-C", "course" : [ "语文", "数学", "英语", "科学" ] }
{ "_id" : ObjectId("5bea316f16d1fcb72bc0dd49"), "name" : "测试-D", "course" : [ "数学", "英语", "科学" ] }

db.students.find({'course':/科/})
{ "_id" : ObjectId("5be93fd616d1fcb72bc0dd48"), "name" : "测试-C", "course" : [ "语文", "数学", "英语", "科学" ] }
{ "_id" : ObjectId("5bea316f16d1fcb72bc0dd49"), "name" : "测试-D", "course" : [ "数学", "英语", "科学" ] }

db.students.find().sort({'age':-1})
{ "_id" : ObjectId("5be927af16d1fcb72bc0dd45"), "name" : "刘琦", "sex" : "女", "age" : 21, "score" : 0, "address" : "上城区" }
{ "_id" : ObjectId("5be9274916d1fcb72bc0dd42"), "name" : "李思", "sex" : "男", "age" : 20, "score" : 69, "address" : "拱墅区" }
{ "_id" : ObjectId("5be9271d16d1fcb72bc0dd41"), "name" : "张三", "sex" : "男", "age" : 19, "score" : 89, "address" : "西湖区" }
{ "_id" : ObjectId("5bea488e16d1fcb72bc0dd4a"), "name" : "王木木-A", "sex" : "男", "age" : 19, "score" : 89, "address" : "西湖区", "course" : [ "语文", "数学" ], "parents" : [ { "name" : "王木木-A-父亲", "age" : 55 }, { "name" : "王木木-A-母亲", "age" : 56 } ] }
{ "_id" : ObjectId("5bea48ed16d1fcb72bc0dd4b"), "name" : "王木木-B", "sex" : "男", "age" : 19, "score" : 89, "address" : "西湖区", "course" : [ "语文", "英语" ], "parents" : [ { "name" : "王木木-B-父亲", "age" : 51 }, { "name" : "王木木-B-母亲", "age" : 53 } ] }
{ "_id" : ObjectId("5be9277416d1fcb72bc0dd43"), "name" : "王五", "sex" : "女", "age" : 18, "score" : 100, "address" : "余杭区" }
{ "_id" : ObjectId("5be9278a16d1fcb72bc0dd44"), "name" : "赵柳", "sex" : "女", "age" : 17, "score" : 66, "address" : "余杭区" }
{ "_id" : ObjectId("5be93fb416d1fcb72bc0dd46"), "name" : "测试-A", "course" : [ "语文", "数学", "英语" ] }
{ "_id" : ObjectId("5be93fc016d1fcb72bc0dd47"), "name" : "测试-B", "course" : [ "语文", "数学" ] }
{ "_id" : ObjectId("5be93fd616d1fcb72bc0dd48"), "name" : "测试-C", "course" : [ "语文", "数学", "英语", "科学" ] }
{ "_id" : ObjectId("5bea316f16d1fcb72bc0dd49"), "name" : "测试-D", "course" : [ "数学", "英语", "科学" ] }

db.students.find().sort({'$natural':-1})
{ "_id" : ObjectId("5bea48ed16d1fcb72bc0dd4b"), "name" : "王木木-B", "sex" : "男", "age" : 19, "score" : 89, "address" : "西湖区", "course" : [ "语文", "英语" ], "parents" : [ { "name" : "王木木-B-父亲", "age" : 51 }, { "name" : "王木木-B-母亲", "age" : 53 } ] }
{ "_id" : ObjectId("5bea488e16d1fcb72bc0dd4a"), "name" : "王木木-A", "sex" : "男", "age" : 19, "score" : 89, "address" : "西湖区", "course" : [ "语文", "数学" ], "parents" : [ { "name" : "王木木-A-父亲", "age" : 55 }, { "name" : "王木木-A-母亲", "age" : 56 } ] }
{ "_id" : ObjectId("5bea316f16d1fcb72bc0dd49"), "name" : "测试-D", "course" : [ "数学", "英语", "科学" ] }
{ "_id" : ObjectId("5be93fd616d1fcb72bc0dd48"), "name" : "测试-C", "course" : [ "语文", "数学", "英语", "科学" ] }
{ "_id" : ObjectId("5be93fc016d1fcb72bc0dd47"), "name" : "测试-B", "course" : [ "语文", "数学" ] }
{ "_id" : ObjectId("5be93fb416d1fcb72bc0dd46"), "name" : "测试-A", "course" : [ "语文", "数学", "英语" ] }
{ "_id" : ObjectId("5be927af16d1fcb72bc0dd45"), "name" : "刘琦", "sex" : "女", "age" : 21, "score" : 0, "address" : "上城区" }
{ "_id" : ObjectId("5be9278a16d1fcb72bc0dd44"), "name" : "赵柳", "sex" : "女", "age" : 17, "score" : 66, "address" : "余杭区" }
{ "_id" : ObjectId("5be9277416d1fcb72bc0dd43"), "name" : "王五", "sex" : "女", "age" : 18, "score" : 100, "address" : "余杭区" }
{ "_id" : ObjectId("5be9274916d1fcb72bc0dd42"), "name" : "李思", "sex" : "男", "age" : 20, "score" : 69, "address" : "拱墅区" }
{ "_id" : ObjectId("5be9271d16d1fcb72bc0dd41"), "name" : "张三", "sex" : "男", "age" : 19, "score" : 89, "address" : "西湖区" }

skip(n):表示跨过多少数据
limit(n):表示取出的数据行的个数限制

例如:分页显示第一页,每页显示2条:skip(0),limit(2):
》db.students.find().sort({'$natural':1}).skip(0).limit(2)
{ "_id" : ObjectId("5be9271d16d1fcb72bc0dd41"), "name" : "张三", "sex" : "男", "age" : 19, "score" : 89, "address" : "西湖区" }
{ "_id" : ObjectId("5be9274916d1fcb72bc0dd42"), "name" : "李思", "sex" : "男", "age" : 20, "score" : 69, "address" : "拱墅区" }

第二页,每页显示2条:

db.students.find().sort({'$natural':1}).skip(2).limit(2)
{ "_id" : ObjectId("5be9277416d1fcb72bc0dd43"), "name" : "王五", "sex" : "女", "age" : 18, "score" : 100, "address" : "余杭区" }
{ "_id" : ObjectId("5be9278a16d1fcb72bc0dd44"), "name" : "赵柳", "sex" : "女", "age" : 17, "score" : 66, "address" : "余杭区" }

上一篇下一篇

猜你喜欢

热点阅读