MongoDB的聚合看起来相当复杂,如果有人能给我一个很好的,简单的例子让我牢牢掌握基础知识,我会很感激。MongoDB Aggregation,我如何获得一个字段的总和?
想象一个集合,其中包含包含文件名和文件大小的文档。
如何获得所有文件大小的总和?
此外,如何获得仅以字母'a'开头的文件的总和?
MongoDB的聚合看起来相当复杂,如果有人能给我一个很好的,简单的例子让我牢牢掌握基础知识,我会很感激。MongoDB Aggregation,我如何获得一个字段的总和?
想象一个集合,其中包含包含文件名和文件大小的文档。
如何获得所有文件大小的总和?
此外,如何获得仅以字母'a'开头的文件的总和?
下面是使用Asynchronous Java Driver两个查询的示例程序:
package example;
import static com.allanbank.mongodb.builder.AggregationGroupField.set;
import static com.allanbank.mongodb.builder.AggregationGroupId.constantId;
import static com.allanbank.mongodb.builder.QueryBuilder.where;
import java.util.regex.Pattern;
import com.allanbank.mongodb.MongoClient;
import com.allanbank.mongodb.MongoCollection;
import com.allanbank.mongodb.MongoFactory;
import com.allanbank.mongodb.bson.Document;
import com.allanbank.mongodb.bson.builder.BuilderFactory;
import com.allanbank.mongodb.bson.builder.DocumentBuilder;
import com.allanbank.mongodb.bson.element.ArrayElement;
import com.allanbank.mongodb.builder.Aggregate;
public class FileSizeAggregation {
public static void main(String[] args) {
MongoClient client = MongoFactory
.createClient("mongodb://localhost:27017");
MongoCollection collection = client.getDatabase("test").getCollection(
"test");
collection.delete(BuilderFactory.start()); // Clear the collection.
// Create some documents.
DocumentBuilder doc = BuilderFactory.start();
for (char first = 'a'; first <= 'z'; ++first) {
for (char second = 'a'; second <= 'z'; ++second) {
doc.reset();
doc.add("name", new String(new char[] { first, second }));
doc.add("size", 10);
collection.insert(doc);
}
}
// Count all file "sizes".
Aggregate.Builder builder = new Aggregate.Builder();
builder.group(constantId("sum"),
set("total").sum("size"),
set("count").count());
System.out.println(new ArrayElement("pipeline", builder.build()
.getPipeline()));
Iterable<Document> docs = collection.aggregate(builder.build());
for (Document d : docs) {
System.out.println(d);
}
// Count all file sizes that start with "a"
builder.reset();
builder.match(where("name").matches(Pattern.compile("^a")));
builder.group(constantId("sum"),
set("total").sum("size"),
set("count").count());
System.out.println(new ArrayElement("pipeline", builder.build()
.getPipeline()));
docs = collection.aggregate(builder.build());
for (Document d : docs) {
System.out.println(d);
}
}
}
我有计划倾出聚合管道,所以你可以看到它是什么样子的外壳。让我们看看输出。
pipeline : [
{
'$group' : {
'_id' : 'sum',
total : { '$sum' : '$size' },
count : { '$sum' : 1 }
}
}
]
这是第一个查询的管道,总和文件的大小。我们使用“$ group”操作符作为流水线中唯一的阶段。我们分配一个常量id('_id':'sum')将所有文档分组到一个结果文档中。然后总计和计数行将每个文档中的大小字段相加并返回文档计数。这种聚合的结果是这样的:
{
'_id' : 'sum',
total : 6760,
count : 676
}
676文件(26 * 26)和因为每个文件是“10”一共是6760看起来不错。下一个聚合!
这次我们只想总结文件名以字母'a'开头的文件。
pipeline : [
{
'$match' : {
name : { '$regex' : { $regex : '^a' } }
}
},
{
'$group' : {
'_id' : 'sum',
total : { '$sum' : '$size' },
count : { '$sum' : 1 }
}
}
]
唯一真正的变化是,我们在管道中添加一个步骤$组之前过滤或$文档的子集相匹配。在这种情况下,正则表达式'^ a'符合法案。 (双$正则表达式的文件是驾驶员编码JSON方式的副作用。第一$正则表达式是“匹配”操作者和所述第二表示的MongoDB扩展以表示正则表达式。)
{
'_id' : 'sum',
total : 260,
count : 26
}
结果看起来不错。 26份文件和260份总数。
HTH, Rob。
你曾见过此页:http://docs.mongodb.org/manual/tutorial/aggregation-examples/ – 2013-03-04 08:01:08