草庐IT

mongodb - 如何以原子方式将顺序递增的 id 添加到一组名称/id 对中

coder 2023-10-28 原文

我需要将顺序递增的 ID 分配给一组名称。这归结为:

包含下一个要生成的id的字段:curId

包含名称/值对的集合 myset,其中值是 id,name 是名称

问题:

我需要原子地:
1. 检查 myset 是否包含 'name'。如果没有,
2. 使用 $inc.
生成一个新的 id 3. 在 myset 中插入 name/id 对。

我找不到在 mongodb 中执行此操作的方法,至少在不引入竞争条件的情况下。欢迎提出建议。

更新

示例文档(它应该是什么样子)。

在添加 'c' 之前:

{

    "mySet": [
        {
            "name": 'a',
            "value" : 1
        },
        {
            "name": 'b',
            "value" : 2
        }
    ]
}

添加'c'后。返回 3,因为这是分配给“c”的 ID。

{

    "mySet": [
        {
            "name": 'a',
            "value" : 1
        },
        {
            "name": 'b',
            "value" : 2
        },
        {
            "name": 'c',
            "value" : 3
        }
    ]
}

再次尝试添加“c”。 没有任何反应,因为“c”已经存在。但返回“3”,因为这是“c”的 ID。

最佳答案

这是一个简单的方法,它涉及维护与要使用的 nextId 相对应的计数器具有此集合的文档中,并且它涉及一个简单的查找查询和更新。从一个空文档开始:

{ 
  "curId": 1,
  "mySet" : [  ]
}

想要添加下一个“名字”(变量Name)的进程做了如下两个操作:

var Name = "a";
var curId = db.coll.findOne({"mySet.name":{"$ne":Name}},{"_id":0,"curId":1}).curId;

/* curId variable is now 1 */
var result = db.coll.update(
    { "mySet.name" : {"$ne":Name}, "curId":curId },
    { "$push": {"mySet" : {"name":Name,"value":curId} }, "$inc":{"curId":1} }
);

if (result.nModified == 0) {
   print("We lost - someone else must have gotten there first");
}

这里的关键部分是:

  1. 查找查询和更新查询以 Name 为条件尚未在 mySet 中数组“名称”。

  2. 更新查询还包含先前读取的值 curId以确保在我们读取记录后没有其他线程更新记录。

  3. curId字段仅在成功时增加 $push在之前读取 curId 时排列 - 直到我们成功使用 curId可用值,我们不想增加它。

关于mongodb - 如何以原子方式将顺序递增的 id 添加到一组名称/id 对中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24087008/

有关mongodb - 如何以原子方式将顺序递增的 id 添加到一组名称/id 对中的更多相关文章

  1. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  2. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby - 将 Bootstrap Less 添加到 Sinatra - 2

    我有一个ModularSinatra应用程序,我正在尝试将Bootstrap添加到应用程序中。get'/bootstrap/application.css'doless:"bootstrap/bootstrap"end我在views/bootstrap中有所有less文件,包括bootstrap.less。我收到这个错误:Less::ParseErrorat/bootstrap/application.css'reset.less'wasn'tfound.Bootstrap.less的第一行是://CSSReset@import"reset.less";我尝试了所有不同的路径格式,但它

  5. ruby - Chef 执行非顺序配方 - 2

    我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul

  6. ruby-on-rails - 正确的 Rails 2.1 做事方式 - 2

    question的一些答案关于redirect_to让我想到了其他一些问题。基本上,我正在使用Rails2.1编写博客应用程序。我一直在尝试自己完成大部分工作(因为我对Rails有所了解),但在需要时会引用Internet上的教程和引用资料。我设法让一个简单的博客正常运行,然后我尝试添加评论。靠我自己,我设法让它进入了可以从script/console添加评论的阶段,但我无法让表单正常工作。我遵循的其中一个教程建议在帖子Controller中创建一个“评论”操作,以添加评论。我的问题是:这是“标准”方式吗?我的另一个问题的答案之一似乎暗示应该有一个CommentsController参

  7. ruby - 可以通过多少种方法将方法添加到 ruby​​ 对象? - 2

    当谈到运行时自省(introspection)和动态代码生成时,我认为ruby​​没有任何竞争对手,可能除了一些lisp方言。前几天,我正在做一些代码练习来探索ruby​​的动态功能,我开始想知道如何向现有对象添加方法。以下是我能想到的3种方法:obj=Object.new#addamethoddirectlydefobj.new_method...end#addamethodindirectlywiththesingletonclassclass这只是冰山一角,因为我还没有探索instance_eval、module_eval和define_method的各种组合。是否有在线/离线资

  8. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  9. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  10. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

随机推荐