You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js环境中LokiJS的find查询返回错误结果的技术咨询

问题原因与解决方案

这其实是LokiJS的默认特性导致的,不是你的操作有误——LokiJS的查询方法(比如findOne、find)默认返回的是文档对象的直接引用,而不是副本。

当你执行var tyrfing = items.findOne({'name': 'tyrfing'});时,tyrfing变量指向的是LokiJS集合中该文档在内存里的实际对象。所以你直接修改tyrfing.owner = 'updated';的时候,已经直接改变了集合内存中的文档数据,这时候再调用items.find查询,自然会拿到修改后的结果,不需要显式调用保存/更新方法(那些方法主要是用来将内存中的数据持久化到存储介质,比如文件)。

如何得到预期的原始值?

如果你想修改查询结果但不影响集合中的原始文档,需要获取文档的副本,有两种方式:

  1. 使用findOne的clone选项:
// 开启clone选项,返回文档的副本
var tyrfing = items.findOne({'name': 'tyrfing'}, {clone: true});
tyrfing.owner = 'updated';
// 此时集合中的原始文档不会被修改,find查询会返回原始值'Svafrlami'
logObject(items.find({ 'name': 'tyrfing' }));
  1. 手动深拷贝文档对象:
    如果你需要更灵活的拷贝方式,可以用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:49:19