英文:
mongodb add values of keys between two objects
问题
I want to create a matchmaking algo comparing two objects with each other. In detail I have to subtract each key of the objects, resulting in an output object with the subtracted values. However, the tricky part is that the keys might not be defined in one of the objects.
The objects, for example, can look like this:
{
userMDs: {
md1: 0.5,
md2: 0.5,
md3: 1,
md7: -0.5,
md8: 0.5,
md9: 1,
md13: -0.5,
md14: 0.5,
md15: 1,
md19: -0.5,
md20: -1,
md21: 1,
md25: -0.5,
md26: 1
},
matchMDs: {
md1: 0.5,
md2: 0.5,
md3: 1,
md7: -0.5,
md15: 1,
md19: -0.5,
md20: -1,
md21: 1,
md25: -0.5,
md26: 1
}
}
Identifying which keys are matching, I do this logic:
{
$addFields: {
commonKeys: {
$filter: {
input: { $objectToArray: "$userMDs" },
as: "userMD",
cond: { $in: ["$$userMD.k", { $map: { input: { $objectToArray: "$matchMDs" }, as: "matchMD", in: "$$matchMD.k" } }] }
}
}
}
}
This results in a new object called "commonKeys," containing the matching keys. I am now having troubles doing the subtraction for the values of the keys that are existing in both objects.
Is there a way to look over each key of the commonKeys and access both the other objects for the subtraction?
Thanks in advance for any hint...!
英文:
I want to create a matchmaking algo comparing two objects with each other.
In detail I have to substract each key of the objects, resulting into an output object with the subtracted values. However the tricky part is that the keys might not be defined in one of the objects.
The objects e.g. can look like this:
{
userMDs: {
md1: 0.5,
md2: 0.5,
md3: 1,
md7: -0.5,
md8: 0.5,
md9: 1,
md13: -0.5,
md14: 0.5,
md15: 1,
md19: -0.5,
md20: -1,
md21: 1,
md25: -0.5,
md26: 1
},
matchMDs: {
md1: 0.5,
md2: 0.5,
md3: 1,
md7: -0.5,
md15: 1,
md19: -0.5,
md20: -1,
md21: 1,
md25: -0.5,
md26: 1
},
}
Identifying which keys are matching, I do this logic:
{
$addFields: {
commonKeys: {
$filter: {
input: { $objectToArray: "$userMDs" },
as: "userMD",
cond: { $in: ["$$userMD.k", { $map: { input: { $objectToArray: "$matchMDs" }, as: "matchMD", in: "$$matchMD.k" } }] }
}
}
}
},
This results into a new object called "commonKeys", containing the matching keys.
I am now having troubles doing the substraction for the values of the keys that are existing in both objects.
Is there a way to look over each key of the commonKeys and access both the other objects for the substraction?
Thanks in advance for any hint...!
答案1
得分: 0
根据您想要的行为,以下是聚合操作的两个版本。
忽略缺失的键,仅减去存在的值
db.collection.aggregate([
{
$addFields: {
commonKeys: {
$filter: {
input: {
$objectToArray: "$userMDs"
},
as: "userMD",
cond: {
$in: [
"$$userMD.k",
{
$map: {
input: {
$objectToArray: "$matchMDs"
},
as: "matchMD",
in: "$$matchMD.k"
}
}
]
}
}
}
}
},
{
$addFields: {
subtracted: {
$arrayToObject: {
$map: {
input: "$commonKeys",
as: "common",
in: {
k: "$$common.k",
v: {
$round: [
{
$subtract: [
"$$common.v",
{
$ifNull: [
{
$arrayElemAt: [
{
$map: {
input: {
$filter: {
input: {
$objectToArray: "$matchMDs"
},
as: "item",
cond: {
$eq: [
"$$item.k",
"$$common.k"
]
}
}
},
as: "item",
in: "$$item.v"
}
},
0
]
},
0
]
}
]
},
1
]
}
}
}
}
}
}
},
{
$project: {
difference: "$subtracted"
}
}
])
MongoDB Playground Link,您可以在这里测试该聚合操作以确认它是否有效。
减去值,即使键缺失
db.collection.aggregate([
{
$addFields: {
userMDsArr: {
$objectToArray: "$userMDs"
},
matchMDsArr: {
$objectToArray: "$matchMDs"
}
}
},
{
$addFields: {
subtracted: {
$arrayToObject: {
$map: {
input: "$userMDsArr",
as: "userMD",
in: {
k: "$$userMD.k",
v: {
$let: {
vars: {
matchMD: {
$arrayElemAt: [
{
$filter: {
input: "$matchMDsArr",
as: "matchMD",
cond: {
$eq: [
"$$matchMD.k",
"$$userMD.k"
]
}
}
},
0
]
}
},
in: {
$round: [
{
$subtract: [
"$$userMD.v",
{
$ifNull: [
"$$matchMD.v",
0
]
}
]
},
1
]
}
}
}
}
}
}
}
}
},
{
$project: {
_id: 1,
subtracted: 1
}
}
])
MongoDB Playground Link,您可以在这里测试该聚合操作以确认它是否有效。
英文:
Depending on the behaviour you want, here are the 2 versions of the aggregation.
Ignore missing keys, subtract only existing
db.collection.aggregate([
{
$addFields: {
commonKeys: {
$filter: {
input: {
$objectToArray: "$userMDs"
},
as: "userMD",
cond: {
$in: [
"$$userMD.k",
{
$map: {
input: {
$objectToArray: "$matchMDs"
},
as: "matchMD",
in: "$$matchMD.k"
}
}
]
}
}
}
}
},
{
$addFields: {
subtracted: {
$arrayToObject: {
$map: {
input: "$commonKeys",
as: "common",
in: {
k: "$$common.k",
v: {
$round: [
{
$subtract: [
"$$common.v",
{
$ifNull: [
{
$arrayElemAt: [
{
$map: {
input: {
$filter: {
input: {
$objectToArray: "$matchMDs"
},
as: "item",
cond: {
$eq: [
"$$item.k",
"$$common.k"
]
}
}
},
as: "item",
in: "$$item.v"
}
},
0
]
},
0
]
}
]
},
1
]
}
}
}
}
}
}
},
{
$project: {
difference: "$subtracted"
}
}
])
MongoDB Playground Link where you can test this aggregation to see that it works.
Subtract values even of missing keys
db.collection.aggregate([
{
$addFields: {
userMDsArr: {
$objectToArray: "$userMDs"
},
matchMDsArr: {
$objectToArray: "$matchMDs"
}
}
},
{
$addFields: {
subtracted: {
$arrayToObject: {
$map: {
input: "$userMDsArr",
as: "userMD",
in: {
k: "$$userMD.k",
v: {
$let: {
vars: {
matchMD: {
$arrayElemAt: [
{
$filter: {
input: "$matchMDsArr",
as: "matchMD",
cond: {
$eq: [
"$$matchMD.k",
"$$userMD.k"
]
}
}
},
0
]
},
},
in: {
$round: [
{
$subtract: [
"$$userMD.v",
{
$ifNull: [
"$$matchMD.v",
0
]
}
]
},
1
]
}
}
}
}
}
}
}
}
},
{
$project: {
_id: 1,
subtracted: 1
}
}
])
MongoDB Playground Link where you can test this aggregation to see that it works.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论