草庐IT

javascript - Mongoose 不能通过文档数组编辑和版本控制进行扩展吗?

coder 2023-10-27 原文

我正在使用 Node.js 和 MongoDB/Mongoose 开发 Web 应用程序。我们最常用的模型 Record 有很多子文档数组。例如,其中一些包括“评论”、“预订”和“订户”。

在客户端应用程序中,每当用户点击“删除”按钮时,它都会触发一个 AJAX 请求以删除该特定评论的路由。我遇到的问题是,当许多这样的 AJAX 调用同时进入时,Mongoose 会在某些(但不是全部)调用中出现“未找到文档”错误。

发生在快速调用并且一次调用很多的时候。我认为这是由于 Mongoose 中的版本导致文档冲突。我们当前的删除流程是:

  1. 使用 Record.findById() 获取文档
  2. 从适当的数组中删除子文档(例如,使用 comment.remove())
  3. 调用record.save()

我找到了一个解决方案,我可以使用 Record.findByIdAndUpdate 然后使用 $pull 运算符手动更新集合。然而,这意味着我们不能使用任何 mongoose 的中间件并完全失去版本控制。我想得越多,就越意识到会发生这种情况,我将不得不使用 Mongoose 的包装函数,如 findByIdAndUpdatefindAndRemove。我能想到的唯一其他解决方案是将删除尝试放入 while 循环中并希望它起作用,这似乎是一个非常糟糕的修复。

使用 Mongoose 包装器并不能真正解决我的问题,因为它根本不允许我使用任何类型的中间件或 Hook ,这基本上是使用 Mongoose 的巨大好处之一。

这是否意味着 Mongoose 对于快速编辑基本上毫无用处,我还不如使用原生 MongoDB 驱动程序?我是否误解了 Mongoose 的局限性? 我该如何解决这个问题?

最佳答案

Mongoose 的版本化文档数组编辑不可扩展,原因很简单,因为它不是原子操作。因此,您拥有的数组编辑事件越多,两次编辑发生冲突的可能性就越大,并且您将承受代码中的重试/恢复开销。

对于可扩展的文档数组操作,您必须使用带有原子数组更新的update operators : $pull[All], $push[All], $pop, $addToSet, 和 >$。当然,如果您还需要原始文档或生成的文档,也可以将这些运算符与基于 findByIdAndUpdatefindOneAndUpdate 的原子方法一起使用这些运算符.

正如您所提到的,使用 update 而不是 findOne+save 的最大缺点是您的 Mongoose 中间件和验证都不会执行在 更新 期间。但我认为如果您想要一个可扩展的系统,您没有任何选择。我宁愿为更新案例手动复制一些中间件和验证逻辑,也不愿忍受使用 Mongoose 的版本化文档数组编辑的可伸缩性损失。嘿,至少您仍然可以享受 Mongoose 基于模式的更新类型转换的好处!

关于javascript - Mongoose 不能通过文档数组编辑和版本控制进行扩展吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15577848/

有关javascript - Mongoose 不能通过文档数组编辑和版本控制进行扩展吗?的更多相关文章

  1. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  2. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  3. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  4. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  5. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  6. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  7. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

  8. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  9. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  10. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

随机推荐