我有一个像这样的集合
{"foo" : "abc-123", more fields.... }
{"foo" : "abc-456", more fields.... }
{"foo" : "cde-000", more fields.... }
{"foo" : "cde-555", more fields.... }
{"foo" : "else-9991234", more fields.... }
并希望按foo
的第一部分进行分组和计数:
{
"abc": 2,
"cde": 2,
"else": 1
}
我考虑过使用聚合框架,但我不确定如何提取第一部分:
myColl.aggregate([
$project: { firstPart: { ???? '$foo'
答案 0 :(得分:1)
我不确定这是否可以与mongo一起使用。最终你必须在第一部分拆分字符串和组。
如果我是你,我宁愿修改你的架构来添加新字段foo1
,这将是字符串的第一部分。您可以使用foreach
db.collection.find().forEach(function(el){
// here split your el['foo'] and update the el with new `foo1` which will have your first part
})
之后,您可以轻松使用聚合框架。
答案 1 :(得分:1)
很遗憾你需要像这样拆分,否则你可能会在聚合管道中使用$ substr运算符。
但是由于你需要这个功能,你可以使用mapReduce:
db.collection.mapReduce() {
function() {
var parts = this.foo.split("-");
emit( parts[0], 1 );
},
function(key,values){
return values.length;
},
{ "out": { "inline": 1 } }
)
发送到reducer的任何内容都会计算数组中的“值”,只有一个键的任何东西都会绕过reducer,但我们已经返回了1的计数。