MongoDB聚合操作学习

MongoDB聚合操作学习

MongoDB的聚合(Aggregation)是一种通过在文档上进行多个操作的过程,然后将结果生成文档的操作。这些操作可以是针对单个集合中的数据文档的,也可以是针对多个集合中的数据进行计算的。 MongoDB中的聚合操作能够处理大量的数据,并提供了灵活的、高效的数据处理方式。

MongoDB聚合操作通过一系列的管道操作构成,每个管道操作都表示聚合操作的一步。每步操作可以包括各种类型的聚合操作,例如过滤、排序、分组、计算、联接等等。各步操作的输出会传递给下一步操作,最终形成一个数据处理的管道。最后一步操作可以是将结果输出到一个集合中,或直接返回给客户端。

MongoDB聚合操作的结果可以是单个文档,也可以是文档集合。聚合操作可以用于统计、处理、分析、筛选、排序和转换数据等多种使用场景。例如,通过聚合操作可以统计某项业务数据的平均值、总和、最大值、最小值,提取某些字段并进行格式转换等等。

在MongoDB中,聚合操作使用到的管道操作非常丰富,支持多种数据类型和聚合方式,例如:$match、$group、$sort、$project、$lookup等等。在使用聚合操作时,可以根据具体业务需求自由组合和调整各步操作,以达到最优的数据处理效果。

总之,MongoDB的聚合操作具有高性能、灵活、强大的特点,可用于处理和分析大量的数据,是MongoDB中非常重要和常用的功能之一。

简单示例

Java代码如下,基于 Spring Boot 实现了根据姓名、年龄和部门进行人员信息查询的功能:

@RestController
@RequestMapping("/api/person")
public class PersonController {

    @Autowired
    private MongoTemplate mongoTemplate;

    @PostMapping("/addPerson")
    public void addPerson(@RequestBody Person person) {
        // 查询对应的人员和部门文档
        Query personQuery = Query.query(Criteria.where("_id").is(person.getPersonId()));
        Query departmentQuery = Query.query(Criteria.where("_id").is(person.getDepartmentId()));
        Document personDocument = mongoTemplate.findOne(personQuery, Document.class, "person");
        Document departmentDocument = mongoTemplate.findOne(departmentQuery, Document.class, "department");
        // 聚合
        List<Document> pipeline = Arrays.asList(
                new Document("$match", new Document("_id", person.getPersonId())),
                new Document("$lookup", new Document("from", "department").append("localField", "departmentId").append("foreignField", "_id").append("as", "department")),
                new Document("$unwind", "$department"),
                new Document("$project", new Document("_id", 0).append("personId", "$_id").append("name", 1).append("age", 1).append("department", "$department")),
                new Document("$group", new Document("_id", "$personId").append("name", new Document("$first", "$name")).append("age", new Document("$first", "$age")).append("department", new Document("$first", "$department")))
        );
        AggregationResults<Document> results = mongoTemplate.aggregate(Aggregation.newAggregation(pipeline), "person", Document.class);
        Document resultDocument = results.getUniqueMappedResult();
        if (resultDocument != null) {
            // 插入聚合结果
            mongoTemplate.insert(resultDocument, "person_department");
        }
    }

    @GetMapping("/searchPeople")
    public String searchPeople(@RequestParam String name, @RequestParam Integer age, @RequestParam String department) {
        Aggregation agg = Aggregation.newAggregation(
                Aggregation.match(Criteria.where("name").is(name).and("age").is(age).and("department.name").is(department)),
                Aggregation.project().andExclude("_id").andInclude("name").andInclude("age").andInclude("department.name").as("department")
        );
        AggregationResults<Document> results = mongoTemplate.aggregate(agg, "person_department", Document.class);
        return JSON.toJSONString(results.getMappedResults());
    }
}

C#代码,需要使用MongoDB.Driver:

csharpCopy code
using MongoDB.Bson;
using MongoDB.Driver;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
[RoutePrefix("api/person")]
public class PersonController : ApiController
{
    [HttpPost]
    [Route("addPerson")]
    public void AddPerson(Person person)
    {
        MongoClient client = new MongoClient("mongodb://localhost:27017");
        IMongoDatabase database = client.GetDatabase("mydb");
        IMongoCollection<BsonDocument> personCollection = database.GetCollection<BsonDocument>("person");
        IMongoCollection<BsonDocument> departmentCollection = database.GetCollection<BsonDocument>("department");
        // 查询对应的人员和部门文档
        FilterDefinition<BsonDocument> personQuery = Builders<BsonDocument>.Filter.Eq("_id", person.PersonId);
        FilterDefinition<BsonDocument> departmentQuery = Builders<BsonDocument>.Filter.Eq("_id", person.DepartmentId);
        BsonDocument personDocument = personCollection.Find(personQuery).FirstOrDefault();
        BsonDocument departmentDocument = departmentCollection.Find(departmentQuery).FirstOrDefault();
        // 聚合
        List<BsonDocument> pipeline = new List<BsonDocument>()
        {
            new BsonDocument("$match", new BsonDocument("_id", person.PersonId)),
            new BsonDocument("$lookup", new BsonDocument("from", "department").Add("localField", "departmentId").Add("foreignField", "_id").Add("as", "department")),
            new BsonDocument("$unwind", "$department"),
            new BsonDocument("$project", new BsonDocument("_id", 0).Add("personId", "$_id").Add("name", 1).Add("age", 1).Add("department", "$department")),
            new BsonDocument("$group", new BsonDocument("_id", "$personId").Add("name", new BsonDocument("$first", "$name")).Add("age", new BsonDocument("$first", "$age")).Add("department", new BsonDocument("$first", "$department")))
        };
        IAggregateFluent<BsonDocument> results = personCollection.Aggregate<BsonDocument>(pipeline);
        BsonDocument resultDocument = results.FirstOrDefault();
        if (resultDocument != null)
        {
            // 插入聚合结果
            database.GetCollection<BsonDocument>("person_department").InsertOne(resultDocument);
        }
    }
    [HttpGet]
    [Route("searchPeople")]
    public string SearchPeople(string name, int age, string department)
    {
        MongoClient client = new MongoClient("mongodb://localhost:27017");
        IMongoDatabase database = client.GetDatabase("mydb");
        IMongoCollection<BsonDocument> collection = database.GetCollection<BsonDocument>("person_department");
        FilterDefinition<BsonDocument> filter = Builders<BsonDocument>.Filter.And(Builders<BsonDocument>.Filter.Eq("name", name), Builders<BsonDocument>.Filter.Eq("age", age), Builders<BsonDocument>.Filter.Eq("department.name", department));
        List<BsonDocument> results = collection.Find(filter).ToList();
        return results.ToJson();
    }
}
posted @ 2023-05-17 22:55  AJun816  阅读(170)  评论(0编辑  收藏  举报