MongoDB 根据现有字段计算分数并将其放入同一集合中的新字段中

2024-03-24

我正在研究 Mongodb,并且我有一个集合,比方说Collection1.

我必须计算现有字段的分数Collection1,并将结果放入新字段Field8 in Collection1.

收藏1:

db.Collection1.find().pretty().limit(2) {
      "_id": ObjectId("5717a5d4578f3f2556f300f2"),
      "Field1": "XXXX",
      "Field2": 0,
      "Field3": 169,
      "Field4": 230,
      "Field5": "...4.67", // This field refer to days in a week
      "Field6": "ZZ",
      "Field7": "LO"
    }, {
      "_id": ObjectId("17a5d4575f300f278f3f2556"),
      "Field1": "YYYY",
      "Field2": 1,
      "Field3": 260,
      "Field4": 80,
      "Field5": "1.3....", // This field refer to days in a week
      "Field6": "YY",
      "Field7": "PK"
    }

所以,我必须使用以下公式对我的第一个集合的字段进行一些计算,但我不知道如何进行 ? :

Score = C1*C2*C3*C4

C1 = 10 + 0.03*field3
C2 = 1 or 0.03 it depends on field2 if it equals 1 or 0
C3 = 1 or 2 .... or 7, it depends on field5 for example C3 for this document "Field5": "...4.67" should return 3, it means three days per week
C4 = 1 or field4^-0.6 if field2 equals 0 or 1

计算完这个分数后我应该把它放在新的字段中Field8 in my Collection1并得到像这样的东西:

 db.Collection1.find().pretty().limit(2) {
          "_id": ObjectId("5717a5d4578f3f2556f300f2"),
          "Field1": "XXXX",
          "Field2": 0,
          "Field3": 169,
          "Field4": 230,
          "Field5": "...4.67", // This field refer to days in a week
          "Field6": "ZZ",
          "Field7": "LO",
          "Field8": Score // My calculated score
        }, {
          "_id": ObjectId("17a5d4575f300f278f3f2556"),
          "Field1": "YYYY",
          "Field2": 1,
          "Field3": 260,
          "Field4": 80,
          "Field5": "1.3....", // This field refer to days in a week
          "Field6": "YY",
          "Field7": "PK",
          "Field8": Score // My calculated score
        }

我怎样才能实现上述目标?


根据您的应用程序需求,您可以使用聚合框架来计算分数并使用bulkWrite() https://docs.mongodb.org/manual/reference/method/db.collection.bulkWrite/#db.collection.bulkWrite更新您的收藏。考虑以下使用以下示例$project https://docs.mongodb.org/manual/reference/operator/aggregation/project/#pipe._S_project管道步骤作为使用算术运算符进行分数计算的余地。

由于计算逻辑C3你的问题是从1 to 7这正好等于7 - number of points (.),我能想到的唯一可行的方法是在进行聚合之前先存储一个额外的字段来保存该值。因此,您的第一步是创建该额外字段,您可以使用bulkWrite() https://docs.mongodb.org/manual/reference/method/db.collection.bulkWrite/#db.collection.bulkWrite如下:


第 1 步:修改架构以容纳额外的内容daysInWeek field

var counter = 0, bulkUpdateOps = [];

db.collection1.find({
    "Field5": { "$exists": true }
}).forEach(function(doc) {
    // calculations for getting the number of points in Field5
    var points, daysInWeek;
    points = (doc.Field5.match(new RegExp(".", "g")) || []).length;
    daysInWeek = 7 - points;
    bulkUpdateOps.push({
        "updateOne": {
            "filter": { "_id": doc._id },
            "update": {
                "$set": { "daysInWeek": daysInWeek }
            }
        }
    });
    counter++;

    if (counter % 500 == 0) {
        db.collection1.bulkWrite(bulkUpdateOps);
        bulkUpdateOps = [];
    }
});

if (counter % 500 != 0) { db.collection1.bulkWrite(bulkUpdateOps); }

理想情况下,上述操作还可以计算问题中的其他常量,从而创建Field8因此。然而,我认为这样的计算应该在客户端完成,并让 MongoDB 在服务器上做它最擅长的事情。


步骤2:使用聚合进行添加Field8 field

创建了那个额外的字段daysInWeek然后,您可以构建一个聚合管道,使用一组数据来投影新变量算术运算符 https://docs.mongodb.org/manual/reference/operator/aggregation-arithmetic/进行计算(再次建议在应用程序层进行此类计算)。最终的投影将是计算字段的乘积,然后您可以使用聚合结果游标进行迭代和添加Field8到每个文档的集合:

var pipeline = [
        {
            "$project": {
                "C1": {
                    "$add": [ 
                        10, 
                        { "$multiply": [ "$Field3", 0.03 ] } 
                    ]
                },
                "C2": {
                    "$cond": [
                        { "$eq": [ "$Field2", 1 ] }, 
                        1, 
                        0.03 
                    ]
                },
                "C3": "$daysInWeek",
                "C4": {
                    "$cond": [
                        { "$eq": [ "$Field2", 1 ]  },
                        { "$pow": [ "$Field4", -0.6 ] },
                        1
                    ]
                }
            }
        },
        {
            "$project": {
                "Field8": { "$multiply": [ "$C1", "$C2", "$C3", "$C4" ] }
            }
        }
    ],
    counter = 0,
    bulkUpdateOps = [];

db.collection1.aggregate(pipeline).forEach(function(doc) {
    bulkUpdateOps.push({
        "updateOne": {
            "filter": { "_id": doc._id },
            "update": {
                "$set": { "Field8": doc.Field8 }
            }
        }
    });
    counter++;

    if (counter % 500 == 0) {
        db.collection1.bulkWrite(bulkUpdateOps);
        bulkUpdateOps = [];
    }
});

if (counter % 500 != 0) { db.collection1.bulkWrite(bulkUpdateOps); }

对于 MongoDB>= 2.6 and <= 3.0, 使用批量操作API https://docs.mongodb.org/manual/reference/method/Bulk/您需要使用光标迭代集合的地方forEach() https://docs.mongodb.org/manual/reference/method/cursor.forEach/方法,更新集合中的每个文档。

上述聚合管道中的一些算术运算符在 MongoDB 中不可用>= 2.6 and <= 3.0所以你需要在forEach() https://docs.mongodb.org/manual/reference/method/cursor.forEach/迭代。

使用批量 API 通过批量捆绑每个更新并仅将集合中的每 500 个文档发送到服务器一次进行处理来减少服务器写入请求:

var bulkUpdateOps = db.collection1.initializeUnorderedBulkOp(),
    cursor = db.collection1.find(), // cursor 
    counter = 0;

cursor.forEach(function(doc) {
    // computations
    var c1, c2, c3, c4, Field8;
    c1 = 10 + (0.03*doc.Field3);
    c2 = (doc.Field2 == 1) ? 1: 0.03;
    c3 = 7 - (doc.Field5.match(new RegExp(".", "g")) || []).length;
    c4 = (doc.Field2 == 1) ? Math.pow(doc.Field, -0.6) : 1;
    Field8 = c1*c2*c3*c4;

    bulkUpdateOps.find({ "_id": doc._id }).updateOne({
        "$set": { "Field8": Field8 }
    });

    if (counter % 500 == 0) {
        bulkUpdateOps.execute();
        bulkUpdateOps = db.collection1.initializeUnorderedBulkOp();
    }
})

if (counter % 500 != 0) { bulkUpdateOps.execute(); }    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MongoDB 根据现有字段计算分数并将其放入同一集合中的新字段中 的相关文章

  • mongodb 安装 - 要求?

    有人知道在 mongo 上安装标准 ubuntu 需要多少磁盘空间和内存吗 试图找出我的 VPS 需求 没有最低要求 但我不建议在与网络服务器相同的机器上运行 Mongo MongoDB 自动使用机器上的所有空闲内存作为其缓存 http d
  • MongoDB - 手册参考示例

    我正在读手册参考 http docs mongodb org manual reference database references document referencesMongoDB 数据库参考文档的一部分 但我不太理解 解析引用字段
  • 如何提高 MongoDB 中 update() 和 save() 的性能?

    我正在寻找有关如何在以下情况下提高数据库性能的提示 作为示例应用程序 我今天编写了一个相当简单的应用程序 它使用 Twitter 流 API 来搜索某些关键字 然后将结果存储在 MongoDB 中 该应用程序是用 Node js 编写的 我
  • 从现有 MongoDB 创建可视化的工具[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我接手了一个现有 MongoDB 的项目 我想获得现有数据的视觉图像 图表等 显然 MongoDB 与
  • 如何在没有 Express 的情况下通过 Mongoose 与 MongoDB 交互?

    我想要一个可以牢固掌握 CRUD 操作如何工作的环境 到目前为止 我一直在使用views看看数据是什么样子 但由于明显缺乏灵活性 这种方法并不是那么有洞察力 这就像在黑暗中开车一样 现在我希望能够通过 Mongoose 提供的功能来处理 M
  • 将 $lookup 结果合并到现有数组

    我是 mongo 新手 我需要你的帮助 我有收藏学习计划 这是示例文档 id dGFY garranti typ sk garant en Chairman of study board id 1025769 typ sk predseda
  • 将图像存储在 Mongodb 中并使用 Nodejs 提供服务

    我知道 Mongodb 可以通过两种方式存储图像 通过将图像存储为二进制在常规文档中 通过 Gridfs 管理更大的图像 为简单起见 并且因为我计划服务器的图像很小 所以我将选择选项 1 为了将图像提供给浏览器 我使用的是nodejs 我的
  • $lookup mongodb 中的 $project

    我有一个查询 使用 lookup https docs mongodb com manual reference operator aggregation lookup 加入 两个模型 之后我使用 project https docs mo
  • 如何在MongoDb中保存Timestamp类型值 |爪哇

    从 Java 驱动程序中 我想在 MongoDb 中保存一个类似于下面 json 的文档 ts Timestamp 1421006159 4 我尝试过的选项 选项1 映射 doc new HashMap 1 doc put ts new B
  • 如何解决 MongoWaitQueueFullException?

    我运行一个java程序 它是一个线程执行程序 它将数千个文档插入到mongodb中的表中 我收到以下错误 Exception in thread pool 1 thread 301 com mongodb MongoWaitQueueFul
  • Mongodb 中的读自己写的一致性

    首先 这是Pymongo 文档 http api mongodb org python current examples requests html highlight read 20you 20own 20write 默认情况下 当线程首
  • 在mongodb中编辑子文档N-N关系

    我有一个应用程序 其中article可以链接到多个平台 文章包含平台列表 平台也包含文章列表 有关更多详细信息 请查看我几个月前提出的 stackoverflow 问题 https stackoverflow com a 40377383
  • mongoDB 中的游标隔离

    首先请原谅我问了一个愚蠢的问题 但我是 mongodb 和学习游标的新手 我有一个问题 为什么我们需要游标隔离 手册说 如果文档发生更改 对文档的干预写入操作可能会导致游标多次返回该文档 我无法理解这一点 如果有人可以提供更多说明或举一些例
  • 使用 sidekiq 只执行众多重复作业之一?

    我有一个后台作业 在 MongoDB 上执行映射 归约作业 当用户向文档发送更多数据时 它会启动在文档上运行的后台作业 如果用户发送多个请求 它将启动同一文档的多个后台作业 但实际上只有一个需要运行 有没有办法可以防止多个重复实例 我正在考
  • java.lang.IllegalArgumentException:预期唯一结果或 null,但得到多个! - Spring Data Mongo

    我在用着Spring Boot v2 2 2 RELEASE and Spring Data MongoDB 在此示例中 我正在查找按部门代码执行组并获取该组下的所有员工 样本数据 firstName Laxmi lastName Para
  • 引用 MongoDB Aggregation Pipeline 中的整个文档

    我可以使用 运算符引用 MongoDB 聚合管道中属性的各个值 但是 我如何访问 引用 整个文档 UPDATE 提供一个示例来解释场景 这是我正在尝试做的事情的一个例子 我有一系列推文 每条推文都有一个成员 集群 它指示特定推文属于哪个集群
  • 如何使用 mongo-go-driver 有效地将 bson 转换为 json?

    我想将 bson 转换为mongo go 驱动程序 https github com mongodb mongo go driver有效地转换为 json 我应该小心处理NaN 因为json Marshal失败如果NaN存在于数据中 例如
  • 检查字段是否存在于数组的子文档中

    我有一个与此类似的架构 id Number line items id String quantity Number review request sent Boolean total price String name String or
  • FieldPath 字段名称不能包含“.”当尝试使用 AGGREGATE 时

    我的查询有什么问题吗 db table aggregate match gt expr gt and gt eq gt size gt events 4 events 0 updated gt lt gt 2019 05 05 我越来越 M
  • 如何使用 MongoDB 实现 ASP.NET Core 3.1 Identity?

    是一个 API 用于简化后端和逻辑代码来管理用户 密码 个人资料数据 角色 声明 令牌 电子邮件确认等 对于 Visual Studio 来说 支撑脚手架 https learn microsoft com en us aspnet cor

随机推荐