我有一个包含大量数据的mongodb存储库,我需要在给定输入的情况下搜索和分类数据。
我计划让服务器工作来处理请求并给出响应,但我不确定使用哪种算法,bigdata工具甚至mongodb命令。
这是我需要做的一个例子。
我有这个数据库:
[
{
id: 1,
Colors: ["Green","Red","Blue","Yellow"]
},
{
id: 2,
Colors: ["Green","Red","Blue"]
},
{
id: 3,
Colors: ["Green","Red"]
},
{
id: 4,
Colors: ["Green"]
}
]
然后我有了这个输入
String x = "Green Red"
或类似
的JSON { Colors: ["Green","Red"]}
然后它将返回与此输入匹配的数据:
[
{
id: 4,
Colors: ["Green"],
Matches: 100%
}
{
id: 3,
Colors: ["Green","Red"],
Matches: 100%
},
{
id: 2,
Colors: ["Green","Red","Blue"],
Matches: 66%
},
{
id: 1
Colors: ["Green","Red","Blue","Yellow"],
Matches: 50%
}
]
答案 0 :(得分:1)
简单来说,您希望通过源输入中的正匹配来$filter
数组,然后将生成的$size
与原始匹配进行比较。版本之间的技术略有不同,但基本上是:
db.getCollection('junk').aggregate([
{ "$addFields": {
"Matches": {
"$trunc": {
"$multiply": [
{ "$divide": [
{ "$size": {
"$filter": {
"input": "$Colors",
"as": "c",
"cond": { "$in": [ "$$c", ["Green","Red"] ] }
}
}},
{ "$size": "$Colors" }
]},
100
]
}
}
}}
])
只要比较值和数组都包含“唯一”元素,您就可以使用$setIntersection
而不是使用$filter
。
db.getCollection('junk').aggregate([
{ "$addFields": {
"Matches": {
"$trunc": {
"$multiply": [
{ "$divide": [
{ "$size": {
"$setIntersection": [ "$Colors", ["Green", "Red"] ]
}},
{ "$size": "$Colors" }
]},
100
]
}
}
}}
])
如果您没有$trunc
或$floor
,则只需使用$mod
和$subtract
进行数学运算即可丢弃余数:
db.getCollection('junk').aggregate([
{ "$project": {
"id": 1,
"Colors": 1,
"Matches": {
"$let": {
"vars": {
"perc": {
"$multiply": [
{ "$divide": [
{ "$size": {
"$setIntersection": [ "$Colors", ["Green", "Red"] ]
}},
{ "$size": "$Colors" }
]},
100
]
}
},
"in": {
"$subtract": [ "$$perc", { "$mod": [ "$$perc", 1 ] } ]
}
}
}
}}
])
虽然一般保持相同的原则。
“匹配数除以数组总长度等于匹配百分比”