参考 > MongoDB CRUD操作 > MongoDB CRUD概念 > 通过可线性化的读取 findAndModify
从副本集读取数据时,有可能读取过时的数据(即可能不反映读取操作之前发生的所有写操作)或不持久的数据(即数据的状态可能反映未进行写操作的数据)。由多数成员或副本集成员确认,因此可以回滚),具体取决于所使用的读取关注点。
从版本3.4开始,MongoDB引入了
"linearizable"
读取问题,该问题会返回未过期的持久数据。Linearizable
阅读关注保证仅在阅读操作指定唯一标识单个文档的查询过滤器时适用。
本教程概述了另一种过程,该过程
db.collection.findAndModify()
用于读取使用MongoDB 3.2进行部署的不陈旧且无法回滚的数据。对于MongoDB 3.4,尽管可以应用概述的过程,但请参阅
"linearizable"
阅读关注。
findAndModify
此过程用于db.collection.findAndModify()
读取不是过时且无法回滚的数据。为此,该过程使用findAndModify()
具有写关注的方法来修改文档中的伪字段。具体来说,该过程要求:
db.collection.findAndModify()
使用完全匹配查询,并且必须存在唯一索引 才能满足该查询。findAndModify()
必须实际修改文档;即导致文档更改。findAndModify()
必须使用写关注
。{ w: "majority" }
重要
“仲裁读取”过程比仅使用读取问题要花费大量成本,"majority"
因为它会导致写入延迟而不是读取延迟。仅在绝对无法忍受过时的情况下才应使用此技术。
本教程从名为的集合中读取内容products
。使用以下操作初始化集合。
该集合中的文档包含一个虚拟字段_dummy_field
,该字段
db.collection.findAndModify()
在本教程中将通过递增
。如果该字段不存在,则该db.collection.findAndModify()
操作会将字段添加到文档中。该字段的目的是确保db.collection.findAndModify()
对文档进行修改。
findAndModify
读取提交的数据。¶使用此db.collection.findAndModify()
方法对要阅读的文档进行简单更新,然后返回修改后的文档。需要写关注。要指定要阅读的文档,必须使用唯一索引支持的完全匹配查询。{ w: "majority" }
以下findAndModify()
操作在唯一索引的字段上指定完全匹配,sku
并递增_dummy_field
匹配文档中命名的字段。尽管不是必需的,但此命令的写关注点还包括毫秒的wtimeout值,5000
以防止如果写不能传播到大多数有表决权的成员,则该操作将永远阻塞。
即使在副本集中的两个节点认为它们是主节点的情况下,也只有一个节点能够使用完成写入
。这样,只有当客户端已连接到真正的主节点以执行操作时,具有写关注的
方法
才会成功。w: "majority"
findAndModify()
"majority"
由于仲裁读取过程只会增加文档中的虚拟字段,因此您可以安全地重复调用
findAndModify()
,并根据需要调整
wtimeout。