前n个字母等于name属性

时间:2016-10-14 07:49:39

标签: mongodb mongodb-query aggregation-framework

我有mongo collection person,其名称值如下:

aaaaaa
aaaabb
aaabbb
aabbcc
aabccc
aacccc

我想找到前三个字母相同的所有名字。所以结果应该是这样的:

count: 3, [aaaaaa, aaaabb, aaabbb]
count: 2, [aabbcc, aabccc]
count: 1, [aacccc]

我知道这是某种聚合,但我自己找不到完全匹配查询。

有这样的疑问吗?

2 个答案:

答案 0 :(得分:3)

您可以使用$substr阶段中的$project运算符来获取名称的前n个字符(n前缀)。 $substr用于从字符串中获取子字符串。然后,有一个$group阶段按前缀分组,并使用$sum运算符计算组中的名称,并使用$push运算符将名称添加到列表中。 (可选)具有$sort阶段,按计数排序。

您的管道看起来像:

db.person.aggregate([
    {"$project":
        {"name":1, 
        "3name":{"$substr":["$name", 0, 3]}
        }
    }, 
    {"$group": 
        {"_id":"$3name", 
        nameList:{"$push" : "$name"}, 
        "count":{"$sum":1}
        }
    }, 
    {"$sort" : {"count":-1}}
])

示例输出:

{ "_id" : "aaa", "nameList" : [ "aaaaaa", "aaaabb", "aaabbb" ], "count" : 3 }
{ "_id" : "aab", "nameList" : [ "aabbcc", "aabccc" ], "count" : 2 }
{ "_id" : "aac", "nameList" : [ "aacccc" ], "count" : 1 }

或者您可以直接在$ group阶段拥有$ substr。

db.person.aggregate([        
    {"$group": 
        {"_id":{"$substr":["$name", 0, 3]}, 
        nameList:{"$push" : "$name"}, 
        "count":{"$sum":1}
        }
    }, 
    {"$sort" : {"count":-1}}
])

答案 1 :(得分:0)

我不认为单个查询可以实现它,但正如您所说聚合具有范围。我不会写出确切的聚合,但可以提出一个管道的想法,在我看来可以实现它。

首先你需要在管道中使用$ project创建一个新的valiable say前缀,该值应该是人名的前三个字母,如prefix: { $substr: [ "$name", 0, 3 ] }

其次在管道中,您可以在创建的前缀变量上调用$ group,并使用$ sum:1来获取计数。

这将为您提供一个文档列表,其中每个前缀都是名称的计数。

您可以通过不同方式增强获取更多数据或数据。