1. 概述

在这个教程中,我们将学习如何通过键名从 MongoDB 中检索值。我们将探索MongoDB的各种方法,根据应用的过滤器获取文档的关键字段名称。首先,我们将使用*find**findOne*方法获取所需数据,然后使用*aggregation*方法。我们将分别在MongoDB shell查询和Java驱动代码中编写查询。

接下来,让我们看看在MongoDB中通过字段名检索值的不同方式。

2. 数据库初始化

首先,我们需要设置一个新的数据库baeldung和一个新的集合travel

use baeldung;
db.createCollection(travel);

现在,我们使用MongoDB的insertMany方法向集合中添加一些示例数据:

db.travel.insertMany([
{ 
    "passengerId":145,
    "passengerName":"Nathan Green",
    "passengerAge":25,
    "sourceStation":"London",
    "destinationStation":"Birmingham",
    "seatType":"Slepper",
    "emailAddress":"[email protected]"
},
{ 
    "passengerId":148,
    "passengerName":"Kevin Joseph",
    "passengerAge":28,
    "sourceStation":"Manchester",
    "destinationStation":"London",
    "seatType":"Slepper",
    "emailAddress":"[email protected]"
},
{ 
    "passengerId":154,
    "passengerName":"Sheldon burns",
    "passengerAge":26,
    "sourceStation":"Cambridge",
    "destinationStation":"Leeds",
    "seatType":"Slepper",
    "emailAddress":"[email protected]"
},
{ 
    "passengerId":168,
    "passengerName":"Jack Ferguson",
    "passengerAge":24,
    "sourceStation":"Cardiff",
    "destinationStation":"Coventry",
    "seatType":"Slepper",
    "emailAddress":"[email protected]"
}
]);

上述insertMany查询将返回以下JSON:

{
    "acknowledged" : true,
    "insertedIds" : [
        ObjectId("623d7f079d55d4e137e47825"),
    ObjectId("623d7f079d55d4e137e47826"),
    ObjectId("623d7f079d55d4e137e47827"),
        ObjectId("623d7f079d55d4e137e47828")
    ]
}

至此,我们已将示例数据插入到travel集合中。

3. 使用find方法

find方法在集合上找到并返回符合指定查询条件的文档。如果多个文档满足条件,它将根据磁盘上的文档顺序返回所有文档。此外,在MongoDB中,find方法支持查询参数投影。如果我们指定一个投影参数给find方法,它将只返回包含投影字段的所有文档。

需要注意的是,除非明确移除,否则_id字段始终包含在响应中。

下面演示一下在shell查询中投影关键字段的方法:

db.travel.find({},{"passengerId":1}).pretty();

该查询的响应如下:

{ "_id" : ObjectId("623d7f079d55d4e137e47825"), "passengerId" : 145 }
{ "_id" : ObjectId("623d7f079d55d4e137e47826"), "passengerId" : 148 }
{ "_id" : ObjectId("623d7f079d55d4e137e47827"), "passengerId" : 154 }
{ "_id" : ObjectId("623d7f079d55d4e137e47828"), "passengerId" : 168 }

在这个查询中,我们仅投影了passengerId字段。现在,让我们看看排除_id字段的关键字段:

db.travel.find({},{"passengerId":1,"_id":0}).pretty();

上述查询将得到以下响应:

{ "passengerId" : 145 }
{ "passengerId" : 148 }
{ "passengerId" : 154 }
{ "passengerId" : 168 }

在这个查询中,我们从响应投影中排除了_id字段。以下是该查询的Java驱动代码:

MongoClient mongoClient = new MongoClient("localhost", 27017);
DB database = mongoClient.getDB("baeldung");
DBCollection collection = database.getCollection("travel");
BasicDBObject queryFilter = new BasicDBObject();
BasicDBObject projection = new BasicDBObject();
projection.put("passengerId", 1);
projection.put("_id", 0);
DBCursor dbCursor = collection.find(queryFilter, projection);
while (dbCursor.hasNext()) {
    System.out.println(dbCursor.next());
}

在上面的代码中,首先我们创建了一个连接到本地Mongo服务器(端口27017)的MongoClient。接着,我们使用find方法,该方法有两个参数:查询过滤器和投影。查询DBObject包含我们需要获取数据的过滤条件。这里,我们使用DBCursor打印出旅行文档的所有投影字段。

4. 使用aggregation方法

MongoDB的aggregation操作处理数据记录和文档,并返回计算结果。它从各个文档中收集值,然后对分组数据执行不同类型的操作,如求和、平均值、最小值、最大值等。

当我们需要进行更复杂的聚合时,可以使用MongoDB的聚合管道。聚合管道是一系列阶段的组合,与MongoDB查询语法结合,产生聚合结果。

让我们看看聚合查询,以通过键名检索值:

db.travel.aggregate([
{
    "$project":{
        "passengerId":1
    }
}
]).pretty();

上述聚合查询的响应如下:

{ "_id" : ObjectId("623d7f079d55d4e137e47825"), "passengerId" : 145 }
{ "_id" : ObjectId("623d7f079d55d4e137e47826"), "passengerId" : 148 }
{ "_id" : ObjectId("623d7f079d55d4e137e47827"), "passengerId" : 154 }
{ "_id" : ObjectId("623d7f079d55d4e137e47828"), "passengerId" : 168 }

在这个例子中,我们使用了聚合管道的$project阶段。$project指定了要包括或排除的字段。在我们的查询中,我们仅将passengerId传递给投影阶段。

下面是该查询的Java驱动代码:

ArrayList<Document> response = new ArrayList<>();
ArrayList<Document> pipeline = new ArrayList<>(Arrays.asList(new Document("$project", new Document("passengerId", 1L))));
database = mongoClient.getDatabase("baeldung");
database.getCollection("travel").aggregate(pipeline).allowDiskUse(true).into(response);
System.out.println("response:- " + response);

我们也可以这样编写聚合管道:

ArrayList<Document> response = new ArrayList<>();
ArrayList<Bson> pipeline = new ArrayList<>(Arrays.asList(
  project(fields(Projections.exclude("_id"), Projections.include("passengerId")))));
MongoDatabase database = mongoClient.getDatabase("baeldung");
database.getCollection("travel").aggregate(pipeline).allowDiskUse(true).into(response);
System.out.println("response:- "+response);

在Java驱动代码中,我们创建了一个聚合管道,并只设置了passengerId字段的投影。最后,我们将聚合管道传递给aggregate方法以获取数据。

5. 总结

在这篇文章中,我们学会了在MongoDB中通过键名检索值。我们探讨了MongoDB的不同方法来获取数据。首先,我们使用find方法获取数据,然后使用aggregate方法。我们研究了MongoDB中字段投影的用法。简而言之,我们使用Mongo shell查询和Java驱动代码实现了字段投影的实现。

你可以在GitHub上找到所有案例的实现。