4. 数据库操作 4.1~4.2

只要是数据库那么就绝对离不开最为核心的功能: CRUD, 所以在MongoDB里面对于数据的操作也是支持的, 但是除了增加之外, 其他操作都是很麻烦的。

4.1 数据增加

  • 使用 db.collection.insert() 可以实现数据的增加操作

增加一个简单数据

db.insert({"url": "www.mldn.cn"})

如果要想保存多个数据就使用数组
范例: 保存数组

 db.infos.insert([
  {'url': 'www.mldn.cn'},
  {'url': 'www.mldnjavascript.cn'}
])
  • 如果保存多条以上数据就
    范例: 保存10000个数据
for ( var i = 0 ; i < 10000 ; i++ ) {
  db.infos.insert( { "url": "mldn - " + i } )
}

如果数据保存很多的情况下, 列表不会全部列出, 它只会列出部分的内容

4.2 数据查询

任何的数据库之中, 数据的查询操作都是最为麻烦的, 而在MongoDB数据库里面, 对于查询的支持非常到位, 包含有关系运算、逻辑运算、数组运算、正则运算等

首先对于数据的查询操作核心的语法: db.collection.find({查询条件}, {设置显示的字段})

范例: 最简单的用法就是直接使用find()函数完成查询

db.infos.find()

范例:希望查询出url为"www.mldn.cn"的数据

db.infos.find({"url": "www.mldn.cn"})

发现在进行数据查询的时候也是按照JSON的形式设置的相等关系.它的整个开发之中不可能离开JSON数据

对于设置的显示字段严格来讲究就称为数据的投影操作, 如果不需要显示的字段设置"0", 而需要显示的字段设置"1"

范例: 不想显示"_id"

db.infos.find({"url": "www.mldn.cn"}, {"_id": 0})
db.infos.find({"url":"www.mldn.cn"}, {"_id":0, "url": 1})

大部分情况下, 这种投影的意义不大. 同时对于数据的查询也可以使用"pretty()"函数

范例: 漂亮显示

db.infos.find({"url":"www.mldn.cn", {"_id":0,"url":1}).pretty()

数据列多的时候一定可以看出华丽的显示效果

范例: 查询单个数据

db.infos.findOne({"url":"www.mldn.cn"}).pretty()

利用以上的查询可以实现数据格式化输出效果, 前提: 列的内容必须多。

4.2.1 关系运算

在MongoDB里面支持的关系查询操作: 大于($gt)、小于($lt)、 大于等于($gte)、小于等于($lte)、不等于($ne)、等于($eq)

范例: 定义一个学生信息集合

db.students.insert({name: '张三', sex: '男', age: 19, score: 59, address: '海淀区'})
db.students.insert({name: '李四', sex: '女', age: 20, score: 99, address: '朝阳区'})
db.students.insert({name: '王五', sex: '女', age: 19, score: 100, address: '西城区'})
db.students.insert({name: '赵六', sex: '男', age: 30, score: 20, address: '东城区'})
db.students.insert({name: '孙七', sex: '男', age: 19, score: 0, address: '海淀区'})
db.students.insert({name: '王八', sex: '女', age: 25, score: 70, address: '朝阳区'})
db.students.insert({name: '刘九', sex: '男', age: 17, score: 56, address: '海淀区'})
db.students.insert({name: '钱十', sex: '女', age: 19, score: 89, address: '西城区'})

范例: 查询姓名是张三的学生信息

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

范例: 查询性别是男的学生信息

db.students.find({"sex": "男"}).pretty()

范例: 查询年龄大于19的学生

db.students.find("age": {"$gt": 19}).pretty()

范例: 查询成绩大于等于60分的学生

db.students.find({score:{"$gte": 60}}).pretty()

范例: 查询姓名不是王五的信息

db.students.find("name": {"$ne": "王五"}).pretty()

此时与之前最大的区别就在于, 在一个JSON结构里面需要定义其他的JSON结构, 并且这种风格在日后通过程序进行操作的时候依然如此.

4.2.2.逻辑运算

逻辑运算主要就是三种类型: 与($and) 、或($or)、非($nor、$not)
范例: 查询年龄在 19~20岁的学生信息

db.students.find({age:[ {"$gte": 19},{"$lte": 20}]}).pretty()

在进行逻辑运算”$and"的连接最容易, 因为只需要利用","分割若干个条件就可以了。

范例: 查询年龄不是19岁的学生

db.students.find({"age": {"$ne": 19}}).pretty()

范例: 查询年龄大于19岁, 或者成绩大于90分的学生信息

db.students.find({"$or": [
{
  "age": {"$gt": 19}
},
{
  "score": {"$gt": 90}
}
]}).pretty()

范例: 也可以进行或的求反操作

db.students.find({"$nor": [
  {
    "age": {"$gt": 19}
  },
  {
    "score": {"$gt": 90}
  }
]}).pretty()

针对于或的求反操作可以实现一个求反的操作
在这几个逻辑运算之中, 与的连接最简单, 而或的连接需要为数据设置数组的过滤条件

4.2.3.求模

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

范例: 求模

db.students.find({"age": {"$mod": [20, 1]}}).pretty()

4.2.4范围查询

只要是数据库, 必须存在有"$in"(在范围之中)、"$nin"( 不再范围之中 )

范例: 查询姓名是"张三", "李四", "王五"的信息

db.students.find({"name": {"$in": ["张三", "李四", "王五"]}).pretty()

范例: 不在范例

db.students.find({"name": {"$nin": ["张三", "李四", "王五"]}).pretty()

4.2.5数组查询

首先在MongoBD里面是支持数组保存的, 一旦支持了数组保存, 就需要针对于数组的数据进行匹配.

范例:保存一部分数组内容

db.students.insert([
{
  name: '谷大神_A',
  sex: '男',
  age: 19,
  score: 89,
  address: '海淀区',
  course: ['语文', '数学', '英语', '音乐', '政治']
}])

db.students.insert([
{
  name: '谷大神_B',
  sex: '男',
  age: 19,
  score: 89,
  address: '海淀区',
  course: ['语文', '数学']
}])

db.students.insert([
{
  name: '谷大神_A',
  sex: '男',
  age: 19,
  score: 89,
  address: '海淀区',
  course: ['语文', '数学', '英语']
}])

db.students.insert([
{
  name: '谷大神_A',
  sex: '男',
  age: 19,
  score: 89,
  address: '海淀区',
  course: [ '英语', '音乐', '政治']
}])

db.students.insert([
{
  name: '谷大神_A',
  sex: '男',
  age: 19,
  score: 89,
  address: '海淀区',
  course: [ '语文', '政治']
}])

此时的数据包含有数据内容, 而后需要针对于数据数据进行判断, 可以使用几个运算符: $all、$slice、$size、$elemMatch

范例: 查询同时参加语问和数学课程的学生

现在两个数组内容都需要保存, 所以使用{$all: [内容一, 内容二, ...]}

db.students.find({"course": {"$all": ["语文","数学"]}}).pretty()

现在所有显示的学生信息里面包含语文和数学的内容, 而如果差一个内容就不会显示。
虽然"$all" 计算可以用于数组上, 但是也可以用于一个数据的匹配上。

范例: 查询学生地址是"海淀区"的信息

db.students.find({"address": {"$all": ["海淀区"]}).pretty()

既然在集合里面现在保存的是数组信息,那么数组就可以利用索引操作,使用"key.index"的方法来定义索引

范例: 查询数组中第二个内容(index = 1, 索引下标从0开始)为数学的信息

db.students.find({"course.1":"数学"}).pretty()

范例: 要求查询出只参加2门课程的学生

使用$size来进行数量的控制

db.students.find("course: {"$size": 2}).pretty()

发现在进行数据查询的时候只要内容符合条件, 数字的内容就全部显示出来了, 但是现在希望可以控制数组的返回的数量, 那么可以使用"$slice"进行控制。

范例: 返回年龄为19岁所有学生的信息, 但是要求只显示两门参加课程.

db.students.find("age": 19, {"course": {"$slice": 2}}).pretty()

现在只取出前两门的信息,那么也可以设置负数表示取出后两门的信息.

db.students.find({"age": 19}, {"course": {"$slice": -2}}).pretty()

或者只是取出中间部分的信息

db.students.find({"age": 19, {"course": {"$slice: [1, 2]}}}).pretty()
在此时设置的两个数据里面第一个数据表示跳过的数据量, 而第二个表示返回的数量

而$elemMatch操作符输出满足这样条件的文档, 即文档中filed数据中至少一个元素满足全部知道指定的匹配要求

db.students.insert({
 resultes: [82, 85, 88, {product: 'xyz}]
})

db.students.find({"resultes": {"$elemMatch": {"$gt": 84,"$lt": 886}}).pretty()

此时85刚好满足 全部要求
还有一种单一条件查询

db.students.find({"resultes": {"$elemMatch": {product: 'xyz}}).pretty()

上面的例子中,因为 $elemMatch 操作符只指定一个查询条件,那么当只有一个查询条件时,使用 $elemMatch 操作符有点大材小用了,你可以将上面的查询替换成下面这样子:

db.students.find({"resultes.product":"xyz"}).pretty()

4.2.6.嵌套集合运算

在MongoDB数据里面每一个集合数据都可以继续保存其他的集合数据, 例如: 有些学生需要保存家长信息

范例: 增加数据

db.students.drop()
db.students.insert({name: '高大拿 - A',sex: '男', age: 19, score: 89, address: '海淀区',
course: ['语文', '数学', '英语', '音乐', '政治'],
parents: [
{name: '高大拿 -A (父亲)', age: 50, job: '工人'},
{name: '高大拿 -A (母亲)', age: 46, job: '职员'}]})

db.students.insert({name: '高大拿 - B',sex: '男', age: 19, score: 89, address: '海淀区',
course: ['语文', '数学'],
parents: [
{name: '高大拿 -B (父亲)', age: 50, job: '处长'},
{name: '高大拿 -B (母亲)', age: 46, job: '局长'}]})

db.students.insert({name: '高大拿 - C',sex: '男', age: 19, score: 89, address: '海淀区',
course: ['语文', '数学', '英语'],
parents: [
{name: '高大拿 -C (父亲)', age: 50, job: '工人'},
{name: '高大拿 -C (母亲)', age: 46, job: '局长'}]})

此时给出的内容是嵌套的集合,而这种集合的数据的判断只能过通过$elemMatch完成。

范例: 查询出父母是局长的信息

db.students.find({
 "$and": [
   {"$gte": 19},
   {"parents": {
     "$elemMatch": {job: '局长”}
   }} 
  ]
}).pretty()

由于这种查询的时候条件比较麻烦, 所以如果可能, 尽量别搞这么复杂的数据结构组成.

4.2.7. 判断某个字段是否存在

使用"$exists"可以判断某个字段是否存在, 如果设置为True表示存在, 如果设置为false就表示不存在.

范例: 查询具有parents的成员的数据

db.students.find({"parents": {"$exists": true}}).pretty()

范例: 查询不具有course成员的数据

db.students.find({"course": {$exists: false}}).pretty()
可以利用此类查询来进行一些不需要的数据过滤.

4.2.8 条件过滤

实际上习惯于传统关系型数据库开发的我们对于数据的筛选, 可以首先想到的一定是where子句, 所以在MongoDB里面也提供有'$where'.

范例: 使用where进行数据查询

db.students.find({"$where": "this.age > 20"}).pretty()

db.students.find("this.age > 20").pretty()

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

db.students.find(function() {
  return this.age > 20
}).pretty()
db.students.find({"$where": function() {
   return this.age > 20
}}).pretty()

以上只是查询了一个判断, 如果要想实现多个条件的判断, 那么就需要使用and连接.

db.students.find({"$and":  [
  {"$where": "this.age > 19"},
  {"$where": "this.age < 21"}
]}).pretty()

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

4.2.9 正则运算

如果要想实现模糊查询, 那么必须使用正则表达式, 而且正则表达式使用的语言是Perl兼容的正则表达式的形式. 如果要想实现正则使用, 则按照以下的定义格式:
基础语法: {key: 正则标记}
. 完整语法: {key: {"$regex": 正则标记, "$options": 选项}}
|- 对于options主要是设置正则的信息查询的标记
|- 'i' : 忽略字母大小写
|- 'm': 多行查找

|- 'x': 空白字符串除了被转义的或在字符类中意外的完全被忽略

|- 's': 匹配所有的字符(圆点: '.'), 包括换行内容.
|-需要注意的是, 如果是直接使用(javascript )那么只能够使用i和m, 而'x'和’s'必须使用'$regex'

范例: 查询以 '谷'开头的姓名

db.students.find("name": /谷/).pretty()

范例: 查询姓名有字母A

db.students.find({"name": /a/i|).pretty()

db.students.find({"name': {"$regex": /a/i}}).pretty()

如果要执行模糊查询的操作, 严格来讲只需要编写一个关键字就够了
正则操作之中除了可以查询出单个字段的内容之外, 也可以进行数组数据的查询.

范例: 查询数组数据

db.students.find({"course":/语?/}).pretty()

db.students.find({"course":/语/}).pretty()

MongoDB中的正则符号和之前Java正则式有一些小小差别, 不建议使用以前的一些标记.正则就将其应用在模糊数据查询上.

4.2.10 数据排序

在 MongoDB里面数据的排序操作使用"sort"函数, 在进行排序的时候可以有两个顺序: 升序(1)、 降序(-1)

范例: 数据排序

db.students.find().sort({"score": -1}).pretty()

但是在进行排序的过程里面有一种方式称为自然排序, 按照数据保存的先后顺序排序, 使用"$natural"表示

范例: 自然排序

db.students.find().sort({"$natural": -1}).pretty()

在MongoDB数据库里面排序的操作相比较传统关系型数据库的设置要简单.

4.2.11 数据分页显示

在MongoDB里面的数据分页显示也是符合大数据要求的操作函数.
.skip(n) : 表示跨过多少数据行;
.limit(n):取出的数据行的个数限制

: 分页显示(第一页, skip(0)、limit(5))

db.students.find().skip(0).limit(5).sort({"age": -1}).pretty()

范例: 分页显示(第二页, skip()、limit(5))

db.students.find().skip(5).limit(5).sort({"age": -1}).pretty()

这两个分页的控制操作, 就是在以后只要是存在有大数据的信息情况下都会使用它.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容