MongoDB入门系列 ===; 应用补充

Posted 刘翾

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MongoDB入门系列 ===; 应用补充相关的知识,希望对你有一定的参考价值。

全系列目录

该系列前几篇所遗漏知识点补充

文章目录

1. 数据库引用

可以在一条数据里面, 保存相关数据库的引用

格式: $ref : , $id : , $db :

三个字段表示的意义为:

  • $ref:集合(表)名称
  • $id:引用的id
  • $db: 数据库名称,可选参数

例:

// 有一条这样的数据

   "_id":ObjectId("53402597d852426020000002"),
   "address": 
   "$ref": "address_home",
   "$id": ObjectId("534009e4d852427820000002"),
   "$db": "runoob",
   "contact": "987654321",
   "dob": "01-01-1991",
   "name": "Tom Benzamin"


// 现在我想查询address字段(field)里面的内容, 注意这里要使用findOne
// 如果使用find的话, 要写明index位置, 例如let a = db.gkd.findOne( b: 123 )[0]
let a = db.gkd.findOne( b: 123 )
let asd = a.caonima
db[asd.$ref].find("_id": asd.$id)

// 该例子来源于菜鸟教程: http://www.runoob.com/mongodb/mongodb-database-references.html

2. findAndModify 查找并修改

没学这个命令之前是, 先find数据, 然后使用remove 或者 update再次操作. 这个命令可以整合这个两个操作为一个

语法:

db.collection.findAndModify(
    query: <document>,
    sort: <document>,
    remove: <boolean>,
    update: <document>,
    new: <boolean>,
    upsert: <boolean>,
    arrayFilters: [ <filterdocument1>, ... ]
);
参数类型描述
querydocument可选, 与find用一个选择器, 注意: 虽然find可能会匹配多个文档, 但findAndModify只会选择一个要修改的文档
sortdocument可选, 排序query查询到的结果, findAndModify会选择排好序的第一条来修改文档
removeboolean必须指定remove或update字段。删除查询字段中指定的文档。将其设置为true可删除所选文档。默认值为false
updatedocument必须指定remove或update字段。执行所选文档的更新。更新字段使用相同的更新运算符或字段
upsertboolean可选, 与update参数结合使用. 当为true的时候, 如果没有文档与查询匹配,则创建新文档, 并插入集合(表)中, 或者更新与查询匹配的单个文档。
newboolean可选, 如果为true,则返回修改后的文档而不是原始文档. 默认为false
arrayFiltersarray一组过滤器, 用于确定一个数组元素应该修改哪些
// 例1
db.people.findAndModify(
    query:  name: "Andy" ,
    sort:  rating: 1 , // rating 升序排列
    update:  $inc:  score: 1  , score增加1
    upsert: true
)

// 例2 数组元素
// student集合(表)中插入数据
db.students.insert([
    "_id" : 1, "grades" : [ 95, 92, 90 ] ,
    "_id" : 2, "grades" : [ 98, 100, 102 ] ,
    "_id" : 3, "grades" : [ 95, 110, 100 ] 
])

// 查找grades大于等于100的文档, 并将值修改为100
db.students.findAndModify(
   query:  grades:  $gte: 100  ,
   update:  $set:  "grades.$[element]" : 100  ,
   arrayFilters: [  "element":  $gte: 100   ]
)

// 结果, 可以看到只有中间的那条数据被修改了, 因为findAndModify只会修改一条数据
 "_id" : 1, "grades" : [ 95, 92, 90 ] 
 "_id" : 2, "grades" : [ 98, 100, 100 ] 
 "_id" : 3, "grades" : [ 95, 110, 100 ] 

2.1 使用findAndModify创造递增列

先说一下思路:
node的大多数做法是, 建一个集合(表)专门用来存储, 其他表的_id递增字段. 之后其他集合每次插入数据的时候, 手动插入对应的_id键
java的话这里有一篇文章是介绍监听saveListener的 https://www.jianshu.com/p/2f292969bec4

下面贴上node代码, java代码可以参考上面的链接, 或者下面的node思路

// 建一个单独的集合, 专门用来记录各个集合最后一个ID
db.counters.insert(
   
      _id: "userid",
      seq: 0
   
)
db.counters.insert(
   
      _id: "productid",
      seq: 0
   
)


// 创建自增函数
function getNextSequence(name) 
   var ret = db.counters.findAndModify(
          
            query:  _id: name ,
            update:  $inc:  seq: 1  ,
            new: true,
            upsert : true // 如果没有匹配到插入一条文档
          
   );

   return ret.seq;



// 这样每次插入数据的时候就可以这样使用
db.users.insert(
   
     _id: getNextSequence("userid"),
     name: "Mr. X",
     // ... more fields
   
)

db.products.insert(
   
     _id: getNextSequence("productid"),
     name: "Mr. Y",
     // ... more fields
   
)

3. 建立索引

语法:

db.collection.createIndex(keys, options)

Key为你要创建的索引字段,1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1

查看 查询结果是否调用了索引, 使用如下函数

db.collection.find().explain()

返回的参数的详细解释: https://docs.mongodb.com/manual/reference/explain-results/index.html

4. 时间戳

之前在系列的第一篇中介绍过ObjectId https://blog.csdn.net/c_kite/article/details/85777134 在这里稍微回忆一下, MongoDB自动生成的ObjectId的组成部分: ObjectId 是一个12字节 BSON(binary json) 类型数据, 前4个字节表示时间戳, 接下来的3个字节是机器标识码, 紧接的2个字节由进程id组成PID, 最后三个字节是随机数.

具体实现代码可以参考: https://github.com/mongodb/mongo-java-driver/blob/master/bson/src/main/org/bson/types/ObjectId.java

接下来举一个例子如果获取ObjectId中的时间戳

const id = db.gkd.find(a: 147)[0];
console.log(id._id.getTimestamp());

以上是关于MongoDB入门系列 ===; 应用补充的主要内容,如果未能解决你的问题,请参考以下文章

❤️一文快速入门MongoDB数据库❤️

❤️一文快速入门MongoDB数据库❤️

《MongoDB入门教程》第12篇 查询结果排序

《MongoDB入门教程》第12篇 查询结果排序

《MongoDB入门教程》第12篇 查询结果排序

MongoDB入门系列 ===; 创建用户