大家好!
我试着找了3天的解决方案,但找不到任何解决办法。希望你们能帮我。
数据
{
'item': 'pen-1',
'colors': [ 'yellow', 'green', 'blue', 'red', 'pink', 'purple' ] //total: 6
},
{
'item': 'pen-2',
'colors': [ 'green', 'blue','pink', 'purple' ] //total: 4
}这是我到目前为止所做的查询:
var col = ['yellow', 'red', 'blue'];
db.getCollection('data').aggregate([
{ $match: { colors : { $in : col } } },
{ $group: { _id: { 'item': '$item', colors: { $size : '$colors' } } } }
])和结果
{
"_id" : {
"item" : "pen-1",
"colors" : 6
}
}
{
"_id" : {
"item" : "pen-2",
"colors" : 4
}
}我想做的是:
返回项目,返回总计的(颜色/颜色匹配),因此它将如下所示:
"_id" : {
"item" : "pen-1",
"rank": 0.5 // total colors(6) / that match(3)
}
"_id" : {
"item" : "pen-2",
"rank": 0.25 // total colors(4) / that match(1)
}发布于 2017-03-13 07:14:57
您可以使用$setIntersection操作符,它接受两个或多个数组,并返回一个数组,该数组包含每个输入数组中出现的元素。然后可以使用$size返回结果数组中的元素数,以获得匹配的总颜色。
如果使用MongoDB 3.4及更高版本,那么$addFields将允许您在文档中添加一个额外字段,而无需显式投影其余字段,否则$project就足够了。
下面的示例说明了这一点:
var col = ['yellow', 'red', 'blue'];
db.getCollection('data').aggregate([
{ "$match": { "colors": { "$in": col } } },
{
"$addFields": {
"rank": {
"$divide": [
{ "$size": { "$setIntersection": ["$colors", col] } },
{ "$size": "$colors" }
]
}
}
},
{ "$sort": { "rank": 1 } }
])样本输出
/* 1 */
{
"_id" : ObjectId("58c645eaf3d1c82da16279a6"),
"item" : "pen-2",
"colors" : [
"green",
"blue",
"pink",
"purple"
],
"rank" : 0.25
}
/* 2 */
{
"_id" : ObjectId("58c645eaf3d1c82da16279a5"),
"item" : "pen-1",
"colors" : [
"yellow",
"green",
"blue",
"red",
"pink",
"purple"
],
"rank" : 0.5
}发布于 2017-03-13 07:11:54
下面是如何从第3.4节开始在MongoDB中这样做:
var colors = ['red', 'pink'];
db.getCollection('test').aggregate([
//Filtering out the records where colors array is empty
//To avoiding dividing by zero.
{
$match: {
'colors.0': {$exists: true}
}
},
{
$addFields: {
matchingColors: {
$filter: {
input: '$colors',
as: 'color',
cond: {'$in': ['$$color', colors]}
}
}
}
},
{
$project: {
item: '$item',
score: {$divide: [{$size: '$matchingColors'}, {$size: '$colors'}]}
}
}
]);
https://stackoverflow.com/questions/42757391
复制相似问题