首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有排名/搜索计数的Mongodb

具有排名/搜索计数的Mongodb
EN

Stack Overflow用户
提问于 2017-03-13 05:57:16
回答 2查看 1.5K关注 0票数 2

大家好!

我试着找了3天的解决方案,但找不到任何解决办法。希望你们能帮我。

数据

代码语言:javascript
复制
{       
 'item': 'pen-1', 
 'colors': [ 'yellow', 'green', 'blue', 'red', 'pink', 'purple' ] //total: 6
  },
  {
 'item': 'pen-2', 
 'colors': [ 'green', 'blue','pink', 'purple' ] //total: 4
 }

这是我到目前为止所做的查询:

代码语言:javascript
复制
var col = ['yellow', 'red', 'blue'];
db.getCollection('data').aggregate([
            { $match: { colors : { $in : col } } },
            { $group: { _id: { 'item': '$item',  colors: { $size : '$colors' } } } }
          ])

和结果

代码语言:javascript
复制
{
    "_id" : {
        "item" : "pen-1",
        "colors" : 6
    }
}
{
    "_id" : {
        "item" : "pen-2",
        "colors" : 4
    }
}

我想做的是:

返回项目,返回总计的(颜色/颜色匹配),因此它将如下所示:

代码语言:javascript
复制
"_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)
    }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-03-13 07:14:57

您可以使用$setIntersection操作符,它接受两个或多个数组,并返回一个数组,该数组包含每个输入数组中出现的元素。然后可以使用$size返回结果数组中的元素数,以获得匹配的总颜色。

如果使用MongoDB 3.4及更高版本,那么$addFields将允许您在文档中添加一个额外字段,而无需显式投影其余字段,否则$project就足够了。

下面的示例说明了这一点:

代码语言:javascript
复制
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 } }            
])

样本输出

代码语言:javascript
复制
/* 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
}
票数 3
EN

Stack Overflow用户

发布于 2017-03-13 07:11:54

下面是如何从第3.4节开始在MongoDB中这样做:

代码语言:javascript
复制
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'}]}
		}
	}
]);

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42757391

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档