Node.js环境中LokiJS的find查询返回错误结果的技术咨询
问题原因与解决方案
这其实是LokiJS的默认特性导致的,不是你的操作有误——LokiJS的查询方法(比如findOne、find)默认返回的是文档对象的直接引用,而不是副本。
当你执行var tyrfing = items.findOne({'name': 'tyrfing'});时,tyrfing变量指向的是LokiJS集合中该文档在内存里的实际对象。所以你直接修改tyrfing.owner = 'updated';的时候,已经直接改变了集合内存中的文档数据,这时候再调用items.find查询,自然会拿到修改后的结果,不需要显式调用保存/更新方法(那些方法主要是用来将内存中的数据持久化到存储介质,比如文件)。
如何得到预期的原始值?
如果你想修改查询结果但不影响集合中的原始文档,需要获取文档的副本,有两种方式:
- 使用
findOne的clone选项:
// 开启clone选项,返回文档的副本 var tyrfing = items.findOne({'name': 'tyrfing'}, {clone: true}); tyrfing.owner = 'updated'; // 此时集合中的原始文档不会被修改,find查询会返回原始值'Svafrlami' logObject(items.find({ 'name': 'tyrfing' }));
- 手动深拷贝文档对象:
如果你需要更灵活的拷贝方式,可以用JSON.parse(JSON.stringify(...))或者其他深拷贝工具:
var tyrfingOriginal = items.findOne({'name': 'tyrfing'}); // 深拷贝得到副本 var tyrfing = JSON.parse(JSON.stringify(tyrfingOriginal)); tyrfing.owner = 'updated'; // 集合中的原始文档依然保持不变 logObject(items.find({ 'name': 'tyrfing' }));
如果你确实想修改集合中的文档
如果你的目标是更新集合里的文档,那么在修改引用对象后,需要调用update方法来确保修改被标记为需要持久化(内存中已经生效,但持久化到存储需要这个操作):
var tyrfing = items.findOne({'name': 'tyrfing'}); tyrfing.owner = 'updated'; // 通知LokiJS更新该文档,以便后续持久化 items.update(tyrfing);
内容的提问来源于stack exchange,提问作者Ram
相关产品推荐
相关产品推荐

