2

问题是下一个:

获取列表中带有标签的文档,按匹配总数排序

但是他们说使用聚合框架是可能的,这可能吗?

4

2 回答 2

8

是的,可以使用聚合框架。

假设

询问

这种方法迫使您展开结果并使用展开的结果重新评估匹配谓词,因此它确实效率低下。

db.test_col.aggregate(
    {$match: {tags: {$in: ["shirt","cotton","black"]}}}, 
    {$unwind: "$tags"}, 
    {$match: {tags: {$in: ["shirt","cotton","black"]}}}, 
    {$group: {
        _id:{"_id":1}, 
        matches:{$sum:1}
    }}, 
    {$sort:{matches:-1}}
);

预期成绩

{
    "result" : [
        {
            "_id" : {
                "_id" : ObjectId("5051f1786a64bd2c54918b26")
            },
            "matches" : 3
        },
        {
            "_id" : {
                "_id" : ObjectId("5051f1726a64bd2c54918b24")
            },
            "matches" : 2
        },
        {
            "_id" : {
                "_id" : ObjectId("5051f1756a64bd2c54918b25")
            },
            "matches" : 1
        }
    ],
    "ok" : 1
}
于 2012-09-13T15:01:06.757 回答
0

使用$size$setIntersection将有效地解决这个问题,而不会导致内存倍增。

tagList = ['shirt', 'cotton', 'black']

db.test_col.aggregate(
    {$match: {tags: {$in: ["shirt","cotton","black"]}}}, 
    {$project: 
        {"title":1,"tags":1}, 
        {$order: 
            {"$size": 
                {"$setIntersection": [ tagList, "$tags" ]}}, 
    {$sort:{order:-1}}
    );
  1. 首先,我们匹配至少有一个元素匹配的文档。

  2. 然后我们投影我们需要的键/列以及新的订单键/列。顺序是通过计算“数据库中的标签”和“查询中的标签”之间的相交元素的数量来生成的。

  3. 然后我们按降序进行简单排序。这对我有用。类似的问题在这里回答

于 2020-06-03T08:26:10.380 回答