[mongo入门日记]

2024-8-30

authSource是什么?

`authSource` 是 MongoDB 连接字符串中的一个参数,用于指定**认证数据库**(authentication database)。认证数据库是 MongoDB 用来存储用户凭据(用户名和密码)以及权限信息的数据库。当客户端连接到 MongoDB 时,它使用这个数据库来验证用户的身份和权限。

### **为什么需要 `authSource`?**

- 在 MongoDB 中,用户是与一个特定的数据库关联的。该数据库被称为用户的**认证数据库**。
- 当一个用户登录时,MongoDB 会在这个认证数据库中查找用户的凭据信息。
- 如果连接字符串中不指定 `authSource`,MongoDB 会默认在所连接的数据库(即连接字符串中的 `dbname`)中进行认证。

### **什么时候使用 `authSource`?**

1. **用户创建在 `admin` 数据库中:**
   - 默认情况下,大多数管理员用户是在 `admin` 数据库上创建的。
   - 如果你需要连接到其他数据库但使用 `admin` 数据库中的用户进行认证,必须指定 `authSource=admin`。
   - 示例:
     ```go
     mongodb://username:password@host:port/myDatabase?authSource=admin
     ```
   - 这里,MongoDB 会在 `admin` 数据库中查找 `username` 的凭据,然后授权连接和操作 `myDatabase`。

2. **用户创建在非默认数据库:**
   - 如果你的用户是在特定的数据库(例如 `userDB`)中创建的,而不是 `admin`,则需要在连接字符串中指定该数据库为 `authSource`。
   - 示例:
     ```go
     mongodb://username:password@host:port/myDatabase?authSource=userDB
     ```
   - 这会告诉 MongoDB,在 `userDB` 数据库中查找用户凭据,而不在 `myDatabase`(默认数据库)中查找。

### **默认行为**

- 如果未指定 `authSource` 参数,MongoDB 将假设认证数据库是连接字符串中的 `dbname`。
- 例如,如果连接字符串是:
  ```go
  mongodb://username:password@host:port/myDatabase
  ```
  MongoDB 会在 `myDatabase` 数据库中寻找用户 `username` 的凭据。

### **总结**

- `authSource` 指定了 MongoDB 用于认证用户的数据库。
- 如果用户不在连接的数据库中创建,或者用户在 `admin` 数据库中创建但需要访问其他数据库,则必须使用 `authSource` 参数来指定正确的认证数据库。

replaceOne:

一个常见的错误是查询条件匹配到了多个文档,然后更新时由第二个参数产生了重复的 "_id" 值。数据库会抛出错误,任何文档都不会被更新。

updateOne:

使用更新运算符时,"_id" 的值是不能改变的。(注意,整个文档替换时是可以
改变 "_id" 的。)其他键值,包括其他唯一索引的键,都是可以更改的。

Todo:

应该始终使用 $ 修饰符来增加、修改或删除键。常见的错误做法是把键的值通过更新设置成其他值,如以下操作所示:
> db.blog.posts.updateOne({"author.name" : "joe"},... {"author.name" : "joe schmoe"})

这会事与愿违。更新的文档必须包含更新运算符。之前版本的 CRUD API 无法捕捉这种类型的错误。早期的更新方法在这种情况下会简单地进行整个文档的替换。正是这种缺陷促成了新 CRUD API 的诞生。

Todo:$ne 和$addToSet的区别

"$inc" 只能用于整型、长整型或双精度浮点型的值。如果用在其他任何类型(包括很多语言中会被自动转换为数值的类型,比如 null、布尔类型以及数字构成的字符串)的值上,则会导致操作失败:
> db.strcounts.insert({"count" : "1"})
WriteResult({ "nInserted" : 1 })> db.strcounts.update({}, {"$inc" : {"
count" : 1}})WriteResult({  "nMatched" : 0,

"nUpserted" : 0,  "nModified" : 0,  "writeError" : {    "code" : 16837,    "errmsg" : "Cannot apply $inc to a
 value of non-numeric type.    {_id: ObjectId('5726c0d36855a935cb
57a659')} has the field 'count' of    non-numeric type String"  }})

同样,"$inc" 键的值必须为数字类型。不能使用字符串、数组或者其他非数字类型的值。否则会提示错误信息:“Modifier "$inc" allowed for numbers only”。如果需要修改其他类型的值,可以使用 "$set" 或者下面要讲到的数组运算符。

> db.movies.updateOne({"genre" : "horror"},
... {"$push" : {"top10" : {"$each" : [{"nam
e" : "Nightmare on Elm Street",...                                    "rat
ing" : 6.6},...                                   {"nam
e" : "Saw", "rating" : 4.3}],...                        "$slice" : -10,...                        "$sort" : {"rati
ng" : -1}}}})
这样会根据 "rating" 字段的值对数组中的所有对象进行排序,然后保留前 10 个。注意,不能只将 "$slice" 或"$sort" 与 "$push" 配合使用,必须包含 "$each"。

数组运算符只能用于包含数组值的键。例如,不能将元素插入一个整数中,也不能从一个字符串中弹出元素。请使用 "$set" 或 "$inc" 来修改标量值。

不过,在很多情况下,如果不预先查询文档并进行检查,就不知道要修改数组的下标。为了解决这个问题,MongoDB 提供了一个定位运算符 $,它可以计算出查询文档匹配的数组元素并更新该元素。如果有一个名为 John的用户将其名字改为了 Jim,那么可以使用定位运算符在评论中进行替换:
> db.blog.updateOne({"comments.author" : "John"},... {"$set" : {"comments.$.author" : "Jim"}})
定位运算符只会更新第一个匹配到的元素。因此,如果John 发表了多条评论,那么他的名字只会在第一条评论中被改变。

使用数组过滤器进行更新

MongoDB 3.6 引入了另一个用于更新单个数组元素的选项:arrayFilters。此选项使我们能够修改与特定条件匹配的数组元素。如果想隐藏所有拥有 5 个或以上反对的评论,那么可以执行以下操作:
db.blog.updateOne(
    {"post" : post
_id },    { $set: { "com
ments.$[elem].hidden" : t
rue } },    {      arrayFilters
: [ { "elem.votes": { $lt
e: -5 } }]    })
这个语句将 elem 定义为了 "comments" 数组中每个匹配元素的标识符。如果 elem 所标识的评论的 votes 值小于或等于 -5,那么就在 "comments" 文档中添加一个名为 "hidden" 的字段,并将其值设置为 true。

upsert:

upsert 是一种特殊类型的更新。如果找不到与筛选条件相匹配的文档,则会以这个条件和更新文档为基础来创建一个新文档;如果找到了匹配的文档,则进行正常的更新。upsert 用起来非常方便,有了它便不再需要“预置”集合:通常可以使用同一套代码创建和更新文档。

2024-8-1

stOnInsert:

有时候需要在创建文档时对字段进行设置,但在后续更新时不对其进行更改。这就是 "$setOnInsert" 的作用。"$setOnInsert" 是一个运算符,它只会在插入文档时设置字段的值。因此,可以像下面这样做:

save 辅助函数
save 是一个 shell 函数,它可以在文档不存在时插入文档,在文档存在时更新文档

findOneAndDelete、findOneAndReplace 和findOneAndUpdate

他们是原子操作。

find查询

"$lt"、"$lte"、"$gt" 和 "$gte" 都属于比较运算符,分别对应 <、<=、> 和 >=。可以将它们组合使用以查找一个范围内的值。例如,要查询 18 到 30 岁的用户,可以进行如下操作:
> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})

对于文档键值不等于某个特定值的情况,就要使用另外一种条件运算符 "$ne" 了,它表示“不相等”。如果想找到所有用户名不为 joe 的用户,可以像下面这样查询:
> db.users.find({"username" : {"$ne" : "joe"}})
"$ne" 可以用于任何类型的数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值