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上找到所有案例的实现。