gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 03:09:27 32 4
gpt4 key购买 nike

我正在 Mongodb 上工作,我有一个集合,比如说 Collection1 .

我必须根据 Collection1 中的现有字段计算分数,并将结果放入新字段 Field8Collection1 .

集合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在我的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() 更新您的收藏。考虑以下使用 $project 的示例 管道步骤作为算术运算符进行分数计算的余地。

由于计算逻辑C3你的问题是从 1 获取一个号码至7正好等于 7 - number of points (.) ,我能想到的唯一可行的方法是在进行聚合之前先存储一个额外的字段来保存该值。因此,您的第一步是创建该额外字段,您可以使用 bulkWrite() 来完成此操作。 如下:

<小时/>

第 1 步:修改架构以容纳额外的 daysInWeek领域

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领域

创建了额外的字段 daysInWeek然后,您可以构建一个聚合管道,使用一组arithmetic operators来投影新变量。进行计算(再次建议在应用程序层进行此类计算)。最终的投影将是计算字段的乘积,然后您可以使用聚合结果游标进行迭代并添加 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<= 3.0 ,使用Bulk Opeartions API您需要使用光标的 forEach() 迭代集合。 方法,更新集合中的每个文档。

上述聚合管道中的一些算术运算符在 MongoDB 中不可用 >= 2.6<= 3.0因此您需要在 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(); }

关于MongoDB 根据现有字段计算分数并将其放入同一集合中的新字段中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36926618/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com