jjzjj

mongodb - 在原子 FindAndModify 操作中计算最大值

coder 2023-11-02 原文

我想弄清楚是否有可能在 MongoDB 中推送一个元素并同时(原子 FindAndModify 操作)更新数组中元素的最大值。

例子:

{
  "_id": "...",
  "max_value": 10,
  "values": [2, 10, 6]
}

在我插入 20 之后,结果将是:

{
  "_id": "...",
  "max_value": 20,
  "values": [2, 10, 6, 20]
}

将值 20 推送到 values 数组,并在同一原子操作中重新计算 max_value 字段(为 20)。

这可能吗?

最佳答案

编辑:经过进一步思考,我原来的答案是正确的,但很浪费。具体来说,第一步不是必须的,所以这里有一个修改版本:

您可以分两步模拟此过程:

  1. 使用 _idmax_value $lte 您当前尝试插入的值进行查找和修改。由于 _id 是唯一的,您知道只有零个或一个文档可以匹配此查询 - 假设存在具有该 _id 的文档,它在以下情况下为零max_value 大于您插入的值,如果小于或等于则为 1。在更新中,$push 新值,$set max_value

  2. 当且仅当第 1 步失败时,使用 _id 再次查找和修改,并将新值$push 到数组。由于第 1 步失败,我们知道当前 max_value 大于新值,因此我们可以忽略它并只$push 新值。

下面是实现它的示例 Python 代码:

# the_id is the ObjectId of the document we want to modify
# new_value is the new value to append to the list
rslt1 = rslt2 = None

rslt1 = db.collection.find_and_modify(
    {'_id': the_id, 'max_value': {'$lte': new_value}},
    {'$push': {'array': new_value}, '$set': {'max_value': new_value}})

if rslt1 is None:
    rslt2 = db.collection.find_and_modify(
        {'_id': the_id},
        {'$push': {'array': new_value}})

# only one of these will be non-None; this
# picks whichever is non-None and assigns
# it to rslt
rslt = rslt1 or rslt2

(这个原始答案有效,但上面的更新版本更有效。)

您可以通过三个步骤模拟此过程:

  1. 用给定的 _id 找到并修改一个文档 max_value $gt 你的当前值'正在尝试插入。由于 _id 是唯一的,您知道只有零个或一个文档可以匹配此查询 - 假设存在具有该 _id 的文档,它在以下情况下为零max_value 小于您插入的值,如果大于则为 1。此 findAndModify 的更新部分会将新值$push 到数组。

  2. 当且仅当第 1 步失败时,使用 _idmax_value $lte 再次查找和修改您当前的值试图插入。在更新中,$push 新值,$set max_value

  3. 当且仅当第 2 步失败时,使用 _id 再次 findAndModify,并将新值$push 到数组。这涵盖了在第 1 步和第 2 步之间,另一个线程将 max_value 提高到大于您当前插入的值的值的情况。

下面是实现它的示例 Python 代码:

# the_id is the ObjectId of the document we want to modify
# new_value is the new value to append to the list
rslt1 = rslt2 = rslt3 = None
rslt1 = db.collection.find_and_modify(
    {'_id': the_id, 'max_value': {'$gt': new_value}},
    {'$push': {'array': new_value}})

if rslt1 is None:
    rslt2 = db.collection.find_and_modify(
        {'_id': the_id, 'max_value': {'$lte': new_value}},
        {'$push': {'array': new_value}, '$set': {'max_value': new_value}})

if rslt1 is None and rslt2 is None:
    rslt3 = db.collection.find_and_modify(
        {'_id': the_id},
        {'$push': {'array': new_value}})

# only one of these will be non-None; this
# picks whichever is non-None and assigns
# it to rslt
rslt = rslt1 or rslt2 or rslt3

关于mongodb - 在原子 FindAndModify 操作中计算最大值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8508663/

有关mongodb - 在原子 FindAndModify 操作中计算最大值的更多相关文章

  1. ruby - 如何使用 Selenium Webdriver 根据 div 的内容执行操作? - 2

    我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption

  2. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

    我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

  3. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

  4. ruby-on-rails - 需要帮助最大化多个相似对象中的 3 个因素并适当排序 - 2

    我需要用任何语言编写一个算法,根据3个因素对数组进行排序。我以度假村为例(如Hipmunk)。假设我想去度假。我想要最便宜的地方、最好的评论和最多的景点。但是,显然我找不到在所有3个中都排名第一的方法。Example(assumingthereare20importantattractions):ResortA:$150/night...98/100infavorablereviews...18of20attractionsResortB:$99/night...85/100infavorablereviews...12of20attractionsResortC:$120/night

  5. ruby - 在 Ruby 中是否有一种惯用的方法来操作 2 个数组? - 2

    a=[3,4,7,8,3]b=[5,3,6,8,3]假设数组长度相同,是否有办法使用each或其他一些惯用方法从两个数组的每个元素中获取结果?不使用计数器?例如获取每个元素的乘积:[15,12,42,64,9](0..a.count-1).eachdo|i|太丑了...ruby1.9.3 最佳答案 使用Array.zip怎么样?:>>a=[3,4,7,8,3]=>[3,4,7,8,3]>>b=[5,3,6,8,3]=>[5,3,6,8,3]>>c=[]=>[]>>a.zip(b)do|i,j|c[[3,5],[4,3],[7,6],

  6. ruby-on-rails - 如何让 Rails View 返回其关联的操作名称? - 2

    我有一个非常简单的Controller来管理我的Rails应用程序中的静态页面:classPagesController我怎样才能让View模板返回它自己的名字,这样我就可以做这样的事情:#pricing.html.erb#-->"Pricing"感谢您的帮助。 最佳答案 4.3RoutingParametersTheparamshashwillalwayscontainthe:controllerand:actionkeys,butyoushouldusethemethodscontroller_nameandaction_nam

  7. ruby - 获取数组中值的最大连续出现次数 - 2

    下面有没有更优雅的方法来实现这个:输入:array=[1,1,1,0,0,1,1,1,1,0]输出:4我的算法:streak=0max_streak=0arr.eachdo|n|ifn==1streak+=1elsemax_streak=streakifstreak>max_streakstreak=0endendputsmax_streak 最佳答案 类似于w0lf'sanswer,但通过从chunk返回nil来跳过元素:array.chunk{|x|x==1||nil}.map{|_,x|x.size}.max

  8. HarmonyOS原子化服务开发相关术语 - 2

    术语中文解释Ability原子化服务帮助用户完成任务的原子化服务,和用户的意图进行关联。Fulfillment服务履行通过图标,卡片,语音等形式呈现用户意图。开发者通过接口的方式,处理用户意图,返回内容。Intent意图用于表达用户想要达成的目标或完成的任务。HUAWEIAssistant智能助手“无微不智”的个人助手,通过不断的学习用户的使用习惯,不断的为用户提供贴心的精准的便捷的个性化服务。AISearch全局搜索用户可快速搜索关键词,与之匹配的原子化服务则会出现在搜索结果中。SmartService智慧服务用户订阅原子化服务,在到达特定触发条件(时间、地点、事件)后,卡片推送至用户智能助

  9. Postman测试简单操作 - 2

    1、接口请求基本操作1.1例子tips在view的选项可以zoomin调整窗口字帖大小。1、创建一个测试的workspace,并命名为test2、test后面新增一个addrequest3、选择发送GET,URL为一个开源的https://api.apiopen.top/api/sentences获取每日一句4、点击send查看内容Tips:如果提示出现Error:tunnelingsocketcouldnotbeestablished,statusCode=407错误,参照以下解决办法)关于tunnelingsocketcouldnotbeestablished,cause=getaddri

  10. 【Linux操作系统】——网络配置与SSH远程 - 2

    Linux操作系统——网络配置与SSH远程安装完VMware与系统后,需要进行网络配置。第一个目标为进行SSH连接,可以从本机到VMware进行文件传送,首先需要进行网络配置。1.下载远程软件首先需要先下载安装一款远程软件:FinalShell或者xhell7FinalShellxhell7FinalShell下载:Windows下载http://www.hostbuf.com/downloads/finalshell_install.exemacOS下载http://www.hostbuf.com/downloads/finalshell_install.pkg2.配置CentOS网络安装好

随机推荐