一口(很长的)气掌握mongodb基本操作

nosql介绍

nosql,全称是 not only sql, 即“不仅于sql”,相较于关系型数据库,nosql更加灵活,无需去维护复杂的数据关系。数据是json格式,更加直观易读。

mongodb是应用最广泛的一种nosql数据库

mongdb

安装mongodb

以mac为例:

☁  ~  brew install mongodb

开启服务

☁  ~  sudo brew services start mongo
Password:
==> Successfully started `mongodb` (label: homebrew.mxcl.mongodb)

连续服务

☁  ~  mongo
MongoDB shell version v3.4.2
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 4.0.2
WARNING: shell and server versions do not match
Server has startup warnings:
2018-09-08T10:56:57.451+0800 I CONTROL  [initandlisten]
2018-09-08T10:56:57.451+0800 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2018-09-08T10:56:57.451+0800 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2018-09-08T10:56:57.451+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2018-09-08T10:56:57.451+0800 I CONTROL  [initandlisten]

配置文件

☁  mysite  cat /usr/local/etc/mongod.conf
systemLog:
  destination: file
  path: /usr/local/var/log/mongodb/mongo.log
  logAppend: true
storage:
  dbPath: /usr/local/var/mongodb
net:
  bindIp: 127.0.0.1

库操作

查看所有库

> show dbs;
admin   0.000GB
config  0.000GB
local   0.000GB

使用库

> use test; # 如果库不存在,会自动创建该库
switched to db test
> show dbs; # 新建的库没有数据,是不会显示在库列表中的
admin   0.000GB
config  0.000GB
local   0.000GB

删除库

> use test
switched to db test
> db.dropDatabase()
{ "ok" : 1 }

集合操作

创建集合

> db.createCollection('col1')
{ "ok" : 1 }

显示集合

> show collections;
col1

删除集合

> db.col1.drop()
true

文档操作

插入文档

> db.col.insert({ # 创建文档时,如果集合不存在,会自动创建集合
...   'name': '郭靖',
...   'gender': true,
...   'age': 20
... });
WriteResult({ "nInserted" : 1 })

查询文档

> db.col.find() # 查出所有文档
{ "_id" : ObjectId("5b933ce95032d051d0771953") }
{ "_id" : ObjectId("5b933ced5032d051d0771954") }
{ "_id" : ObjectId("5b933d1f565bbd5e857dbd89"), "name" : "郭靖", "gender" : true, "age" : 20 }
> db.col.find({name: '郭靖'}) # 根据条件筛选文档
{ "_id" : ObjectId("5b933d1f565bbd5e857dbd89"), "name" : "郭靖", "gender" : true, "age" : 20 }

更新文档

> db.col.update({'name': '郭靖'}, {$set: {'age': 25}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.col.find({name: '郭靖'})
{ "_id" : ObjectId("5b933d1f565bbd5e857dbd89"), "name" : "郭靖", "gender" : true, "age" : 25 }

删除文档

> db.col.remove({'name': '郭靖'})
WriteResult({ "nRemoved" : 1 })

数据类型

名称 释义
Object ID 文档ID
String 字符串,最常用,必须是有效的UTF-8
Boolean 存储一个布尔值,true或false
Integer 整数可以是32位或64位,这取决于服务器
Double 存储浮点值
Arrays 数组或列表,多个值存储到一个键
Object 用于嵌入式的文档,即一个值为一个文档
Null 存储Null值
Timestamp 时间戳
Date 存储当前日期或时间的UNIX时间格式

object id 每个文档都有一个属性,为_id,保证每个文档的唯一性, objectID是一个12字节的十六进制数
前4个字节为当前时间戳
接下来3个字节的机器ID
接下来的2个字节中MongoDB的服务进程id
最后3个字节是简单的增量值

查询进阶

数据初始化

let data = [
  {'name':'郭靖', 'age':20, 'skill':'降龙十八掌', 'gender':true},
  {'name':'黄蓉', 'age':18, 'skill':'桃花岛武功', 'gender':false},
  {'name':'黄药师', 'age':58, 'skill':'碧海潮生曲', 'gender':true},
  {'name':'一灯大师', 'age':60, 'skill':'一阳指', 'gender':true},
  {'name':'小龙女', 'age':25, 'skill':'玉女心经', 'gender':false},
  {'name':'李莫愁', 'age':30, 'skill':'赤练神掌', 'gender':false},
  {'name':'乔峰', 'age':35, 'skill':'降龙十八掌', 'gender':true},
  {'name':'王语嫣', 'age':22, 'skill':'懂得各派武功', 'gender':false},
]
for (i in data) {
  data[i]
  db.person.insert(data[i])
}
  • findOne
> db.person.findOne(); // 只查询一条
{
    "_id" : ObjectId("5b9363badfee996b08be20af"),
    "name" : "郭靖",
    "age" : 20,
    "skill" : "降龙十八掌",
    "gender" : true
}
> db.person.findOne({'name': '小龙女'});
{
    "_id" : ObjectId("5b9363badfee996b08be20b3"),
    "name" : "小龙女",
    "age" : 25,
    "skill" : "玉女心经",
    "gender" : false
}
  • 比较运算
> db.person.find({age: {$gt: 50}})  // 大于
{ "_id" : ObjectId("5b9363badfee996b08be20b1"), "name" : "黄药师", "age" : 58, "skill" : "碧海潮生曲", "gender" : true }
{ "_id" : ObjectId("5b9363badfee996b08be20b2"), "name" : "一灯大师", "age" : 60, "skill" : "一阳指", "gender" : true }

> db.person.find({age: {$gte: 60}}) // 大于等于
{ "_id" : ObjectId("5b9363badfee996b08be20b2"), "name" : "一灯大师", "age" : 60, "skill" : "一阳指", "gender" : true }

> db.person.find({age: {$lt: 20}}) // 小于
{ "_id" : ObjectId("5b9363badfee996b08be20b0"), "name" : "黄蓉", "age" : 18, "skill" : "桃花岛武功", "gender" : false }

> db.person.find({age: {$lte: 20}}) // 小于等于
{ "_id" : ObjectId("5b9363badfee996b08be20af"), "name" : "郭靖", "age" : 20, "skill" : "降龙十八掌", "gender" : true }
{ "_id" : ObjectId("5b9363badfee996b08be20b0"), "name" : "黄蓉", "age" : 18, "skill" : "桃花岛武功", "gender" : false }
  • 逻辑运算
> db.person.find({$or:[{name:'郭靖'}, {age: {$gt: 50}}]}) // or查询
{ "_id" : ObjectId("5b9363badfee996b08be20af"), "name" : "郭靖", "age" : 20, "skill" : "降龙十八掌", "gender" : true }
{ "_id" : ObjectId("5b9363badfee996b08be20b1"), "name" : "黄药师", "age" : 58, "skill" : "碧海潮生曲", "gender" : true }
{ "_id" : ObjectId("5b9363badfee996b08be20b2"), "name" : "一灯大师", "age" : 60, "skill" : "一阳指", "gender" : true }

> db.person.find({age: {$in: [18, 20]}}) // in查询
{ "_id" : ObjectId("5b9363badfee996b08be20af"), "name" : "郭靖", "age" : 20, "skill" : "降龙十八掌", "gender" : true }
{ "_id" : ObjectId("5b9363badfee996b08be20b0"), "name" : "黄蓉", "age" : 18, "skill" : "桃花岛武功", "gender" : false }
  • 正则查询
> db.person.find({name: /^小/})
{ "_id" : ObjectId("5b9363badfee996b08be20b3"), "name" : "小龙女", "age" : 25, "skill" : "玉女心经", "gender" : false }
  • js函数查询
> db.person.find({$where:function(){return this.age>40}})
{ "_id" : ObjectId("5b9363badfee996b08be20b1"), "name" : "黄药师", "age" : 58, "skill" : "碧海潮生曲", "gender" : true }
{ "_id" : ObjectId("5b9363badfee996b08be20b2"), "name" : "一灯大师", "age" : 60, "skill" : "一阳指", "gender" : true }

> db.person.find({$where:function(){return this.skill.indexOf('掌')>=0}})
{ "_id" : ObjectId("5b9363badfee996b08be20af"), "name" : "郭靖", "age" : 20, "skill" : "降龙十八掌", "gender" : true }
{ "_id" : ObjectId("5b9363badfee996b08be20b4"), "name" : "李莫愁", "age" : 30, "skill" : "赤练神掌", "gender" : false }
{ "_id" : ObjectId("5b9363badfee996b08be20b5"), "name" : "乔峰", "age" : 35, "skill" : "降龙十八掌", "gender" : true }
  • skip与limit
> db.person.find().skip(1).limit(1)
{ "_id" : ObjectId("5b9363badfee996b08be20b0"), "name" : "黄蓉", "age" : 18, "skill" : "桃花岛武功", "gender" : false }
> db.person.find().limit(1).skip(1)
{ "_id" : ObjectId("5b9363badfee996b08be20b0"), "name" : "黄蓉", "age" : 18, "skill" : "桃花岛武功", "gender" : false }

skip与limit可单独,也可组合使用。虽然在这种查询条件下,两者的顺序不会影响结果。但推荐使用skip().limit()的顺序。因为在聚合查询时两者的顺序不同会导致结果不同。

  • 显示字段
> db.person.find({}, {name: 1}); // 查询条件为空时,也要有{}空json,_id默认是显示的
{ "_id" : ObjectId("5b9363badfee996b08be20af"), "name" : "郭靖" }
{ "_id" : ObjectId("5b9363badfee996b08be20b0"), "name" : "黄蓉" }
{ "_id" : ObjectId("5b9363badfee996b08be20b1"), "name" : "黄药师" }
{ "_id" : ObjectId("5b9363badfee996b08be20b2"), "name" : "一灯大师" }
{ "_id" : ObjectId("5b9363badfee996b08be20b3"), "name" : "小龙女" }
{ "_id" : ObjectId("5b9363badfee996b08be20b4"), "name" : "李莫愁" }
{ "_id" : ObjectId("5b9363badfee996b08be20b5"), "name" : "乔峰" }
{ "_id" : ObjectId("5b9363badfee996b08be20b6"), "name" : "王语嫣" }

> db.person.find({}, {name: 1, _id: 0}); // 不显示_id
{ "name" : "郭靖" }
{ "name" : "黄蓉" }
{ "name" : "黄药师" }
{ "name" : "一灯大师" }
{ "name" : "小龙女" }
{ "name" : "李莫愁" }
{ "name" : "乔峰" }
{ "name" : "王语嫣" }
  • sort排序
> db.person.find({}, {_id:0, name:1, age:1}).sort({age: 1}); // 正序
{ "name" : "黄蓉", "age" : 18 }
{ "name" : "郭靖", "age" : 20 }
{ "name" : "王语嫣", "age" : 22 }
{ "name" : "小龙女", "age" : 25 }
{ "name" : "李莫愁", "age" : 30 }
{ "name" : "乔峰", "age" : 35 }
{ "name" : "黄药师", "age" : 58 }
{ "name" : "一灯大师", "age" : 60 }
> db.person.find({}, {_id:0, name:1, age:1}).sort({age: -1}); // 倒序
{ "name" : "一灯大师", "age" : 60 }
{ "name" : "黄药师", "age" : 58 }
{ "name" : "乔峰", "age" : 35 }
{ "name" : "李莫愁", "age" : 30 }
{ "name" : "小龙女", "age" : 25 }
{ "name" : "王语嫣", "age" : 22 }
{ "name" : "郭靖", "age" : 20 }
{ "name" : "黄蓉", "age" : 18 }
  • count统计
> db.person.count()
8
> db.person.count({age: {$gt: 20}})
6
  • distinct过滤重复
> db.person.find({age: {$gt: 20}}, {_id:0, gender:1})
{ "gender" : true }
{ "gender" : true }
{ "gender" : false }
{ "gender" : false }
{ "gender" : true }
{ "gender" : false }
> db.person.distinct('gender', {age: {$gt: 20}})
[ true, false ]

聚合

$group分组

// 按gender字段进行分组
db.person.aggregate([
  {$group:{_id:'$gender'}}
]);

{ "_id" : false }
{ "_id" : true }

// 分组后再进行求和统计:求各个组的记录条数
db.person.aggregate([
  {$group:{_id:'$gender', counter:{$sum: 1}}}
]);

{ "_id" : false, "counter" : 4 }
{ "_id" : true, "counter" : 4 }

// 指定某个字段求和
db.person.aggregate([
  {$group:{_id:'$gender', counter:{$sum: '$age'}}}
]);

{ "_id" : false, "counter" : 95 }
{ "_id" : true, "counter" : 173 }

// 将分组中指定字段的值归为一个数组
db.person.aggregate([
  {$group:{_id:'$gender', counter:{$push: '$name'}}}
]);

{ "_id" : false, "counter" : [ "黄蓉", "小龙女", "李莫愁", "王语嫣" ] }
{ "_id" : true, "counter" : [ "郭靖", "黄药师", "一灯大师", "乔峰" ] }

// 将分组中包括的文档归为一个数组
db.person.aggregate([
  {$group:{_id:'$gender', counter:{$push: '$$ROOT'}}}
]);

{ "_id" : false, "counter" : [ { "_id" : ObjectId("5b9363badfee996b08be20b0"), "name" : "黄蓉", "age" : 18, "skill" : "桃花岛武功", "gender" : false }, { "_id" : ObjectId("5b9363badfee996b08be20b3"), "name" : "小龙女", "age" : 25, "skill" : "玉女心经", "gender" : false }, { "_id" : ObjectId("5b9363badfee996b08be20b4"), "name" : "李莫愁", "age" : 30, "skill" : "赤练神掌", "gender" : false }, { "_id" : ObjectId("5b9363badfee996b08be20b6"), "name" : "王语嫣", "age" : 22, "skill" : "懂得各派武功", "gender" : false } ] }
{ "_id" : true, "counter" : [ { "_id" : ObjectId("5b9363badfee996b08be20af"), "name" : "郭靖", "age" : 20, "skill" : "降龙十八掌", "gender" : true }, { "_id" : ObjectId("5b9363badfee996b08be20b1"), "name" : "黄药师", "age" : 58, "skill" : "碧海潮生曲", "gender" : true }, { "_id" : ObjectId("5b9363badfee996b08be20b2"), "name" : "一灯大师", "age" : 60, "skill" : "一阳指", "gender" : true }, { "_id" : ObjectId("5b9363badfee996b08be20b5"), "name" : "乔峰", "age" : 35, "skill" : "降龙十八掌", "gender" : true } ] }

$match匹配

// 匹配age大于20的文档
db.person.aggregate([ 
  {$match: {age:{$gt:20}}},
]);

{ "_id" : ObjectId("5b9363badfee996b08be20b1"), "name" : "黄药师", "age" : 58, "skill" : "碧海潮生曲", "gender" : true }
{ "_id" : ObjectId("5b9363badfee996b08be20b2"), "name" : "一灯大师", "age" : 60, "skill" : "一阳指", "gender" : true }
{ "_id" : ObjectId("5b9363badfee996b08be20b3"), "name" : "小龙女", "age" : 25, "skill" : "玉女心经", "gender" : false }
{ "_id" : ObjectId("5b9363badfee996b08be20b4"), "name" : "李莫愁", "age" : 30, "skill" : "赤练神掌", "gender" : false }
{ "_id" : ObjectId("5b9363badfee996b08be20b5"), "name" : "乔峰", "age" : 35, "skill" : "降龙十八掌", "gender" : true }
{ "_id" : ObjectId("5b9363badfee996b08be20b6"), "name" : "王语嫣", "age" : 22, "skill" : "懂得各派武功", "gender" : false }

// 在匹配的基础上再进行分组统计
db.person.aggregate([
  {$match: {age:{$gt:20}}},
  {$group: {_id:'$gender', counter:{$sum:1}}}
]);

{ "_id" : false, "counter" : 3 }
{ "_id" : true, "counter" : 3 }

$project显示字段

db.person.aggregate([
  {$match: {age:{$gt:20}}},
  {$group: {_id:'$gender', counter:{$sum:1}}},
  {$project: {_id:0, counter:1}}
]);

{ "counter" : 3 }
{ "counter" : 3 }

$sort排序

db.person.aggregate([
  {$match: {age: {$gt: 20}}},
  {$group: {_id: '$gender', counter: {$sum:1}}},
  {$project: {counter: 1}},
  {$sort: {_id: -1}}
]);

{ "_id" : true, "counter" : 3 }
{ "_id" : false, "counter" : 3 }

skip与limit

// skip 和 limit 在聚合时有顺序区分的。开发时养成先skip,再limit的习惯
db.person.aggregate([
  {$match: {age: {$gt: 20}}},
  {$group: {_id: '$gender', counter: {$sum:1}}},
  {$project: {counter: 1}},
  {$sort: {_id: -1}},
  {$skip: 1},
  {$limit: 1}
]);

{ "_id" : false, "counter" : 3 }

db.person.aggregate([
  {$match: {age: {$gt: 20}}},
  {$group: {_id: '$gender', counter: {$sum:1}}},
  {$project: {counter: 1}},
  {$sort: {_id: -1}},
  {$limit: 1},
  {$skip: 1}
]);
// 结果为空

$unwind

将文档中的数组解开

db.shirt.insert({_id:1, title:'t-shirt', size:['M', 'L', 'S']});
db.shirt.aggregate([
    {$unwind: '$size'}
]);

{ "_id" : 1, "title" : "t-shirt", "size" : "M" }
{ "_id" : 1, "title" : "t-shirt", "size" : "L" }
{ "_id" : 1, "title" : "t-shirt", "size" : "S" }

// unwind作用的字段为不同值时的情况

db.shirt.insert({_id: 2, title: 't2', size:[]});
db.shirt.insert({_id: 3, title: 't3'});
db.shirt.insert({_id: 4, title: 't4', size:null});
db.shirt.insert({_id: 5, title: 't5', size:'M'});

// 空值,没有size的数据丢了
db.shirt.aggregate([
  {$unwind: '$size'}
]);  
{ "_id" : 1, "title" : "t-shirt", "size" : "M" }
{ "_id" : 1, "title" : "t-shirt", "size" : "L" }
{ "_id" : 1, "title" : "t-shirt", "size" : "S" }
{ "_id" : 5, "title" : "t5", "size" : "M" }

// 阻止空值丢失
db.shirt.aggregate([
  {$unwind: {path: '$size', preserveNullAndEmptyArrays:true}}
]);  
{ "_id" : 1, "title" : "t-shirt", "size" : "M" }
{ "_id" : 1, "title" : "t-shirt", "size" : "L" }
{ "_id" : 1, "title" : "t-shirt", "size" : "S" }
{ "_id" : 2, "title" : "t2" }
{ "_id" : 3, "title" : "t3" }
{ "_id" : 4, "title" : "t4", "size" : null }
{ "_id" : 5, "title" : "t5", "size" : "M" }

索引

创建一个一百万文档的集合

for(i=0; i<1000000; i++){
    db.test_index.insert({name:'test'+i, rank:i});
};

WriteResult({ "nInserted" : 1 })

在没有索引的情况下查找数据

db.test_index.find({name: 'test10000'});
{ "_id" : ObjectId("5b937532dfee996b08be47c7"), "name" : "test10000", "rank" : 10000 }
db.test_index.find({name: 'test10000'}).explain('executionStats'); // executionTimeMillis 值为 416 表示执行 416 毫秒

创建索引

db.test_index.ensureIndex({name: 1});
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}

再次分析性能

db.test_index.find({name: 'test10000'}).explain('executionStats'); // executionTimeMillis 降为 8 毫秒

用户权限管理

  1. 创建超级管理员
  2. 修改配置文件,启用身份验证
  3. 重启服务
  4. 使用超级管理员登录
  5. 创建普通用户
  6. 使用普通用户登录

创建用户

db.createUser({
  user:'admin', 
  pwd:'admin123', 
  roles:[{role:'root', db:'admin'}],
  passwordDigestor: 'server'
})

修改配置

security:
    authorization: enabled

重启服务

sudo brew services restart mongo

直接用mongo登录,无法使用show dbs等命令

☁  ~  mongo
MongoDB shell version v3.4.2
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 4.0.2
WARNING: shell and server versions do not match
> db
test
> show dbs;
2018-09-08T09:51:53.531+0800 E QUERY    [thread1] Error: listDatabases failed:{
    "ok" : 0,
    "errmsg" : "command listDatabases requires authentication",
    "code" : 13,
    "codeName" : "Unauthorized"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1
shellHelper.show@src/mongo/shell/utils.js:755:19
shellHelper@src/mongo/shell/utils.js:645:15
@(shellhelp2):1:1

使用超级管理员登录

☁  ~  mongo -u admin -p --authenticationDatabase admin
MongoDB shell version v3.4.2
Enter password:
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 4.0.2
WARNING: shell and server versions do not match
Server has startup warnings:
2018-09-08T09:51:35.534+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2018-09-08T09:51:35.534+0800 I CONTROL  [initandlisten]
> show dbs;
admin   0.000GB
config  0.000GB
local   0.000GB
py3     0.004GB

创建普通用户

db.createUser({
  user:'py3', 
  pwd:'admin123', 
  roles:[{role:'readWrite', db:'py3'}],
  passwordDigestor: 'server'
})

使用普通管理员登录

☁  ~  mongo -u py3 -p --authenticationDatabase py3
MongoDB shell version v3.4.2
Enter password:
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 4.0.2
WARNING: shell and server versions do not match
> show dbs;
py3  0.004GB

普通管理员只能在指定的数据库,无法登录其他数据库

☁  ~  mongo -u py3 -p --authenticationDatabase admin
MongoDB shell version v3.4.2
Enter password:
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 4.0.2
WARNING: shell and server versions do not match
2018-09-08T10:14:02.358+0800 E QUERY    [thread1] Error: Authentication failed. :
DB.prototype._authOrThrow@src/mongo/shell/db.js:1459:20
@(auth):6:1
@(auth):1:2
exception: login failed
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 31,790评论 2 89
  • MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写,旨在为 WEB 应用提供可扩展的高性能数据...
    LittlePy阅读 1,475评论 0 4
  • NoSql数据库优缺点 在优势方面主要体现在下面几点: 简单的扩展 快速的读写 低廉的成本 灵活的数据模型 在不足...
    dreamer_lk阅读 2,609评论 0 6
  • 简介 MongoDB 是一个基于分布式文件存储的NoSQL数据库 由C++语言编写,运行稳定,性能高 旨在为 WE...
    大熊_7d48阅读 33,156评论 1 8
  • 背景 前段时间,生产环境服务器出现了OOM,并没有什么吃内存的功能,服务器分配的内存余量还是很大的,为什么...
    张大虎彡阅读 4,642评论 0 1