228.6. MongoDB 操作 - 生成者端点
228.6.1. 查询操作 复制链接链接已复制到粘贴板!
228.6.1.1. findById 复制链接链接已复制到粘贴板!
此操作仅从其 _id 字段与 IN 消息正文内容匹配的集合中检索一个元素。传入的对象可以是等同于 BSON 类型的任何内容。请参阅 http://bsonspec.org//specification[http://bsonspec.org//specification] 和 http://www.mongodb.org/display/DOCS/Java+Types。
from("direct:findById")
.to("mongodb:myDb?database=flights&collection=tickets&operation=findById")
.to("mock:resultFindById");
from("direct:findById")
.to("mongodb:myDb?database=flights&collection=tickets&operation=findById")
.to("mock:resultFindById");
支持可选参数。此操作支持指定字段过滤器。请参阅 指定可选参数。
228.6.1.2. findOneByQuery 复制链接链接已复制到粘贴板!
使用此操作只从与 MongoDB 查询匹配的集合中检索一个元素。查询对象从 IN 消息正文中提取,即它应该类型为 DBObject 或转换为 DBObject。它可以是 JSON 字符串或 Hashmap。如需更多信息,请参阅 #Type conversions。
没有查询的示例(返回集合的任何对象):
from("direct:findOneByQuery")
.to("mongodb:myDb?database=flights&collection=tickets&operation=findOneByQuery")
.to("mock:resultFindOneByQuery");
from("direct:findOneByQuery")
.to("mongodb:myDb?database=flights&collection=tickets&operation=findOneByQuery")
.to("mock:resultFindOneByQuery");
带有查询的示例(返回一个匹配结果):
from("direct:findOneByQuery")
.setBody().constant("{ \"name\": \"Raul Kripalani\" }")
.to("mongodb:myDb?database=flights&collection=tickets&operation=findOneByQuery")
.to("mock:resultFindOneByQuery");
from("direct:findOneByQuery")
.setBody().constant("{ \"name\": \"Raul Kripalani\" }")
.to("mongodb:myDb?database=flights&collection=tickets&operation=findOneByQuery")
.to("mock:resultFindOneByQuery");
支持可选参数。此操作支持指定字段 filter 和/或 sort 子句。请参阅 指定可选参数。
228.6.1.3. findAll 复制链接链接已复制到粘贴板!
findAll 操作会返回与查询匹配的所有文档,或全部都不匹配,在这种情况下,集合中包含的所有文档都会被返回。查询对象从 IN 消息正文中提取,即它应该类型为 DBObject 或转换为 DBObject。它可以是 JSON 字符串或 Hashmap。如需更多信息,请参阅 #Type conversions。
没有查询的示例(返回集合中的所有对象):
from("direct:findAll")
.to("mongodb:myDb?database=flights&collection=tickets&operation=findAll")
.to("mock:resultFindAll");
from("direct:findAll")
.to("mongodb:myDb?database=flights&collection=tickets&operation=findAll")
.to("mock:resultFindAll");
带有查询的示例(返回所有匹配结果):
from("direct:findAll")
.setBody().constant("{ \"name\": \"Raul Kripalani\" }")
.to("mongodb:myDb?database=flights&collection=tickets&operation=findAll")
.to("mock:resultFindAll");
from("direct:findAll")
.setBody().constant("{ \"name\": \"Raul Kripalani\" }")
.to("mongodb:myDb?database=flights&collection=tickets&operation=findAll")
.to("mock:resultFindAll");
通过以下标头支持分页和有效的检索:
| 标头键 | 快速常数 | 描述(从 MongoDB API 文档中提取) | 预期类型 |
|---|---|---|---|
|
|
| 在光标的开始丢弃指定数量的元素。 | int/Integer |
|
|
| 限制返回的元素数量。 | int/Integer |
|
|
| 限制一个批处理中返回的元素数量。光标通常获取一系列结果对象并将其存储在本地。如果 batchSize 为正数,则代表检索的每个对象批处理的大小。可以调整它以优化性能和限制数据传输。如果 batchSize 为负数,它将限制返回的数量,该对象适合最大批处理大小限制(通常为 4MB),并且光标将关闭。例如,如果 batchSize 是 -10,则服务器将返回最多 10 个文档,且尽可能多的文档可能适合 4MB,然后关闭光标。请注意,这个功能与文件的 limit ()不同,文档必须适合最大大小,它会删除发送请求以关闭光标服务器端。即使光标迭代后,批处理大小也可以更改,在这种情况下,设置将应用到下一个批处理检索。 | int/Integer |
您还可以通过将 outputType=DBCursor (Camel 2.16+)作为端点选项,从服务器返回的文档作为端点选项,它可能比设置上述标头更为简单。这从 Mongo 驱动程序证明您的 Exchange the DBCursor,就如同您在 Mongo shell 中执行 findAll ()一样,允许您的路由迭代结果。默认情况下,如果没有这个选项,此组件会将文档从驱动程序的光标加载到列表中,并返回到您的路由 - 可能会导致大量内存对象。请记住,使用 DBCursor 不询问与文档匹配的数量 - 详情请查看 MongoDB 文档站点。
带有选项 outputType=DBCursor 和批处理大小的示例:
from("direct:findAll")
.setHeader(MongoDbConstants.BATCH_SIZE).constant(10)
.setBody().constant("{ \"name\": \"Raul Kripalani\" }")
.to("mongodb:myDb?database=flights&collection=tickets&operation=findAll&outputType=DBCursor")
.to("mock:resultFindAll");
from("direct:findAll")
.setHeader(MongoDbConstants.BATCH_SIZE).constant(10)
.setBody().constant("{ \"name\": \"Raul Kripalani\" }")
.to("mongodb:myDb?database=flights&collection=tickets&operation=findAll&outputType=DBCursor")
.to("mock:resultFindAll");
findAll 操作也会返回以下 OUT 标头,以便在使用分页时迭代结果页面:
| 标头键 | 快速常数 | 描述(从 MongoDB API 文档中提取) | 数据类型 |
|---|---|---|---|
|
|
| 与查询匹配的对象数量。这不会考虑限制/跳过。 | int/Integer |
|
|
| 与查询匹配的对象数量。这不会考虑限制/跳过。 | int/Integer |
支持可选参数。此操作支持指定字段 filter 和/或 sort 子句。请参阅 指定可选参数。
228.6.1.4. æ•°é‡� 复制链接链接已复制到粘贴板!
返回集合中对象总数,返回 Long 作为 OUT 消息正文。
以下示例将计算"dynamicCollectionName"集合中的记录数。请注意启用动态性的方式,因此操作不会针对"notableScientists"集合运行,而是针对"dynamicCollectionName"集合运行。
// from("direct:count").to("mongodb:myDb?database=tickets&collection=flights&operation=count&dynamicity=true");
Long result = template.requestBodyAndHeader("direct:count", "irrelevantBody", MongoDbConstants.COLLECTION, "dynamicCollectionName");
assertTrue("Result is not of type Long", result instanceof Long);
// from("direct:count").to("mongodb:myDb?database=tickets&collection=flights&operation=count&dynamicity=true");
Long result = template.requestBodyAndHeader("direct:count", "irrelevantBody", MongoDbConstants.COLLECTION, "dynamicCollectionName");
assertTrue("Result is not of type Long", result instanceof Long);
从 Camel 2.14 开始,您可以在消息正文中提供 com.mongodb.DBObject 对象作为查询,并且操作将返回与此条件匹配的文档量。
DBObject query = ...
Long count = template.requestBodyAndHeader("direct:count", query, MongoDbConstants.COLLECTION, "dynamicCollectionName");
DBObject query = ...
Long count = template.requestBodyAndHeader("direct:count", query, MongoDbConstants.COLLECTION, "dynamicCollectionName");
228.6.1.5. 指定字段过滤器(项目) 复制链接链接已复制到粘贴板!
默认情况下,查询操作将返回整个对象(所有字段)。如果您的文档较大,且您只需要检索其字段的子集,您可以在所有查询操作中指定字段过滤器,只需设置相关的 (或者类型转换为 DBObject),如 DBObject CamelMongoDbFieldsFilter 标头上的 JSON String、Map 等。
以下是一个示例,它使用 MongoDB 的 BasicDBObjectBuilder 来简化 DBObjects 的创建。它检索除 _id 和 boringField 以外的所有字段:
// route: from("direct:findAll").to("mongodb:myDb?database=flights&collection=tickets&operation=findAll")
DBObject fieldFilter = BasicDBObjectBuilder.start().add("_id", 0).add("boringField", 0).get();
Object result = template.requestBodyAndHeader("direct:findAll", (Object) null, MongoDbConstants.FIELDS_FILTER, fieldFilter);
// route: from("direct:findAll").to("mongodb:myDb?database=flights&collection=tickets&operation=findAll")
DBObject fieldFilter = BasicDBObjectBuilder.start().add("_id", 0).add("boringField", 0).get();
Object result = template.requestBodyAndHeader("direct:findAll", (Object) null, MongoDbConstants.FIELDS_FILTER, fieldFilter);
228.6.1.6. 指定 sort 子句 复制链接链接已复制到粘贴板!
根据特定字段的排序,通常需要从集合中获取 min/max 记录。在 Mongo 中,操作使用类似如下的语法:
db.collection.find().sort({_id: -1}).limit(1)
// or
db.collection.findOne({$query:{},$orderby:{_id:-1}})
db.collection.find().sort({_id: -1}).limit(1)
// or
db.collection.findOne({$query:{},$orderby:{_id:-1}})
在 Camel 路由中,SORT_BY 标头可与 findOneByQuery 操作一起使用,以达到相同的结果。如果还指定了 FIELDS_FILTER 标头,则操作将返回单个字段/值对,可以直接传递给另一个组件(例如,参数化 MyBatis SELECT 查询)。本例演示了从集合中获取最新的文档,并根据 documentTimestamp 字段将结果减少到单个字段:
228.6.2. 创建/更新操作 复制链接链接已复制到粘贴板!
228.6.2.1. insert 复制链接链接已复制到粘贴板!
将新对象插入到 MongoDB 集合中,从 IN 消息正文获取。类型转换试图将它转换为 DBObject 或 列表。
支持两种模式: 单插入和多个插入。对于多个插入,端点将预期任何类型的对象的 List、Array 或 Collections,只要它们是 - 或可以转换为 DBObject。所有对象都会一次性插入。端点将根据输入智能地决定要调用哪个后端操作(单或多个插入)。
Example:
from("direct:insert")
.to("mongodb:myDb?database=flights&collection=tickets&operation=insert");
from("direct:insert")
.to("mongodb:myDb?database=flights&collection=tickets&operation=insert");
该操作将返回 WriteResult,并根据 WriteConcern 或 invokeGetLastError 选项的值,getLastError () 将已被调用。如果您希望访问些操作的最终结果,可以通过在 WriteResult 上调用 getLastError() 或 getCachedLastError() 来获取 CommandResult。然后,您可以通过调用 CommandResult.ok ()、CommandResult.getErrorMessage () 和/或 CommandResult.getException () 来验证结果。
请注意,新对象的 _id 在集合中必须是唯一的。如果没有指定值,MongoDB 将自动为您生成一个。但是,如果您确实指定它且不是唯一的,插入操作将失败(并且要注意,您需要启用 invokeGetLastError 或设置等待写结果的 WriteConcern)。
这并不是组件的一个限制,但它是在 MongoDB 中用于更高吞吐量的效果。如果您使用自定义 _id,则需要确保在应用程序级别具有唯一性(这也是良好的做法)。
自 Camel 2.15: 插入记录的 OID 存储在 CamelMongoOid 键下的消息标头中(MongoDbConstants.OID constant)中。存储的值为 org.bson.types.ObjectId 用于单个插入或 java.util.List<org.bson.types.ObjectId> (如果插入了多个记录)。
228.6.2.2. save 复制链接链接已复制到粘贴板!
save 操作等同于 upsert (UPdate, inSERT)操作,其中将更新记录,如果记录不存在,它将被插入,所有都在一个原子操作中。MongoDB 将基于 _id 字段执行匹配。
请注意,如果有更新,对象会被完全替换,不允许使用 MongoDB 的 $modifiers。因此,如果要操作对象(如果已存在),有两个选项:
- 执行查询,首先检索整个对象及其所有字段(可能效率低下),在 Camel 中更改它,然后保存它。
- 使用带有 $modifiers 的 update 操作,这将在服务器端执行更新。您可以启用 upsert 标志,在这种情况下,如果需要一个插入,MongoDB 会将 $modifiers 应用到过滤器查询对象并插入结果。
例如:
from("direct:insert")
.to("mongodb:myDb?database=flights&collection=tickets&operation=save");
from("direct:insert")
.to("mongodb:myDb?database=flights&collection=tickets&operation=save");
228.6.2.3. update 复制链接链接已复制到粘贴板!
更新集合中的一个或多个记录。需要一个 List<DBObject> 作为包含完全 2 元素的 IN 消息正文:
- 元素 1 (index 0) navigator filter query determine 确定哪些对象会受到影响,与典型的查询对象相同
- 元素 2 (index 1) package update rules TOKEN 如何更新匹配的对象。支持 MongoDB 中的所有 修饰符操作。
多更新 .默认情况下,即使多个对象与过滤器查询匹配,MongoDB 也会更新 1 对象。要指示 MongoDB 更新 所有匹配 记录,请将 CamelMongoDbMultiUpdate IN 消息标头设置为 true。
将返回一个带有键 CamelMongoDbRecordsAffected 的标头(Affected) (MongoDbConstants.RECORDS_AFFECTED constant),带有更新的记录数(从 WriteResult.getN ())。
支持以下 IN message 标头:
| 标头键 | 快速常数 | 描述(从 MongoDB API 文档中提取) | 预期类型 |
|---|---|---|---|
|
|
| 如果更新应该应用到匹配的所有对象。请参阅 http://www.mongodb.org/display/DOCS/Atomic+Operations | boolean/Boolean |
|
|
| 如果数据库应创建元素(如果它不存在) | boolean/Boolean |
例如,以下命令将 "scientist" 字段的值设置为 "Darwin" 字段来更新其 filterField 字段等于 true 的所有记录:
// route: from("direct:update").to("mongodb:myDb?database=science&collection=notableScientists&operation=update");
DBObject filterField = new BasicDBObject("filterField", true);
DBObject updateObj = new BasicDBObject("$set", new BasicDBObject("scientist", "Darwin"));
Object result = template.requestBodyAndHeader("direct:update", new Object[] {filterField, updateObj}, MongoDbConstants.MULTIUPDATE, true);
// route: from("direct:update").to("mongodb:myDb?database=science&collection=notableScientists&operation=update");
DBObject filterField = new BasicDBObject("filterField", true);
DBObject updateObj = new BasicDBObject("$set", new BasicDBObject("scientist", "Darwin"));
Object result = template.requestBodyAndHeader("direct:update", new Object[] {filterField, updateObj}, MongoDbConstants.MULTIUPDATE, true);
228.6.3. 删除操作 复制链接链接已复制到粘贴板!
228.6.3.1. remove 复制链接链接已复制到粘贴板!
从集合中删除匹配的记录。IN 消息正文将充当删除过滤器查询,并且应该是 DBObject 类型的类型或可转换的类型。
以下示例将删除其字段 'conditionField' 等于 true 的所有对象,在科学数据库中,ableScientists 集合:
// route: from("direct:remove").to("mongodb:myDb?database=science&collection=notableScientists&operation=remove");
DBObject conditionField = new BasicDBObject("conditionField", true);
Object result = template.requestBody("direct:remove", conditionField);
// route: from("direct:remove").to("mongodb:myDb?database=science&collection=notableScientists&operation=remove");
DBObject conditionField = new BasicDBObject("conditionField", true);
Object result = template.requestBody("direct:remove", conditionField);
返回一个带有键 CamelMongoDbRecordsAffected 的标头 (MongoDbConstants.RECORDS_AFFECTED constant) with type int, 包括删除记录的数量 (从 WriteResult.getN() 复制)。
228.6.4. 批量写操作 复制链接链接已复制到粘贴板!
228.6.4.1. bulkWrite 复制链接链接已复制到粘贴板!
从 Camel 2.21 开始提供
批量执行带有控件的写入操作,以便执行顺序。需要一个 List<WriteModel<DBObject >> 作为 IN 消息正文,其中包含用于插入、更新和删除操作的命令。
以下示例将插入一个新的科学家 "Pierre Curie",更新 id 为 "5" 的记录,将 "scientist" 项的值设置为 "Marie Curie" 并删除 id 为 "3" 的记录 :
默认情况下,操作会按顺序执行,并在第一个写入错误时中断操作,而不会处理列表中任何剩余的写操作。要指示 MongoDB 继续处理列表中剩余的写操作,请将 CamelMongoDbBulkOrdered IN message 标头设置为 false。未排序的操作并行执行,无法保证此行为。
| 标头键 | 快速常数 | 描述(从 MongoDB API 文档中提取) | 预期类型 |
|---|---|---|---|
|
|
| 执行有序或未排序的操作执行。默认值为 true。 | boolean/Boolean |
228.6.5. 其他操作 复制链接链接已复制到粘贴板!
228.6.5.1. 聚合 复制链接链接已复制到粘贴板!
从 Camel 2.14 开始提供
使用正文中包含的给定管道执行聚合。聚合可能是长时间和重度的操作。请谨慎使用。
// route: from("direct:aggregate").to("mongodb:myDb?database=science&collection=notableScientists&operation=aggregate");
from("direct:aggregate")
.setBody().constant("[{ $match : {$or : [{\"scientist\" : \"Darwin\"},{\"scientist\" : \"Einstein\"}]}},{ $group: { _id: \"$scientist\", count: { $sum: 1 }} } ]")
.to("mongodb:myDb?database=science&collection=notableScientists&operation=aggregate")
.to("mock:resultAggregate");
// route: from("direct:aggregate").to("mongodb:myDb?database=science&collection=notableScientists&operation=aggregate");
from("direct:aggregate")
.setBody().constant("[{ $match : {$or : [{\"scientist\" : \"Darwin\"},{\"scientist\" : \"Einstein\"}]}},{ $group: { _id: \"$scientist\", count: { $sum: 1 }} } ]")
.to("mongodb:myDb?database=science&collection=notableScientists&operation=aggregate")
.to("mock:resultAggregate");
支持以下 IN message 标头:
| 标头键 | 快速常数 | 描述(从 MongoDB API 文档中提取) | 预期类型 |
|---|---|---|---|
|
|
| 设置每个批处理要返回的文档数量。 | int/Integer |
|
|
| 启用聚合管道阶段,将数据写入临时文件。 | boolean/Boolean |
通过 outputType=DBCursor 支持有效的检索。
您还可以通过将 outputType=DBCursor (Camel 2.21+)作为端点选项,从服务器返回的文档作为端点选项,它可能比设置上述标头更为简单。这通过 Mongo 驱动程序的 Exchange the DBCursor,就如同您在 Mongo shell 中执行 aggregate ()一样,您的路由可以迭代结果。默认情况下,如果没有这个选项,此组件会将文档从驱动程序的光标加载到列表中,并返回到您的路由 - 可能会导致大量内存对象。请记住,使用 DBCursor 不询问与文档匹配的数量 - 详情请查看 MongoDB 文档站点。
带有选项 outputType=DBCursor 和 batch 大小的示例:
228.6.5.2. getDbStats 复制链接链接已复制到粘贴板!
等同于在 MongoDB shell 中运行 db.stats () 命令,该命令显示有关数据库的有用统计图。
例如:
使用示例:
// from("direct:getDbStats").to("mongodb:myDb?database=flights&collection=tickets&operation=getDbStats");
Object result = template.requestBody("direct:getDbStats", "irrelevantBody");
assertTrue("Result is not of type DBObject", result instanceof DBObject);
// from("direct:getDbStats").to("mongodb:myDb?database=flights&collection=tickets&operation=getDbStats");
Object result = template.requestBody("direct:getDbStats", "irrelevantBody");
assertTrue("Result is not of type DBObject", result instanceof DBObject);
此操作将返回与 shell 中显示的数据结构类似的数据结构,格式为 OUT 消息正文中的 DBObject。
228.6.5.3. getColStats 复制链接链接已复制到粘贴板!
等同于在 MongoDB shell 中运行 db.collection.stats () 命令,该命令显示有关集合的有用统计图。
例如:
使用示例:
// from("direct:getColStats").to("mongodb:myDb?database=flights&collection=tickets&operation=getColStats");
Object result = template.requestBody("direct:getColStats", "irrelevantBody");
assertTrue("Result is not of type DBObject", result instanceof DBObject);
// from("direct:getColStats").to("mongodb:myDb?database=flights&collection=tickets&operation=getColStats");
Object result = template.requestBody("direct:getColStats", "irrelevantBody");
assertTrue("Result is not of type DBObject", result instanceof DBObject);
此操作将返回与 shell 中显示的数据结构类似的数据结构,格式为 OUT 消息正文中的 DBObject。
228.6.5.4. 命令 复制链接链接已复制到粘贴板!
从 Camel 2.15 开始提供
在数据库上运行正文作为命令。Usefull 用于 admin 操作作为获取主机信息、复制或分片状态。
此操作不使用集合参数。
// route: from("command").to("mongodb:myDb?database=science&operation=command");
DBObject commandBody = new BasicDBObject("hostInfo", "1");
Object result = template.requestBody("direct:command", commandBody);
// route: from("command").to("mongodb:myDb?database=science&operation=command");
DBObject commandBody = new BasicDBObject("hostInfo", "1");
Object result = template.requestBody("direct:command", commandBody);
228.6.6. 动态操作 复制链接链接已复制到粘贴板!
Exchange 可以通过设置 MongoDbConstants.OPERATION_HEADER 常量所定义的 CamelMongoDbOperation 标头来覆盖端点的固定操作。
支持的值由 MongoDbOperation enumeration 决定,并与端点 URI 上的 operation 参数接受的值匹配。
例如:
// from("direct:insert").to("mongodb:myDb?database=flights&collection=tickets&operation=insert");
Object result = template.requestBodyAndHeader("direct:insert", "irrelevantBody", MongoDbConstants.OPERATION_HEADER, "count");
assertTrue("Result is not of type Long", result instanceof Long);
// from("direct:insert").to("mongodb:myDb?database=flights&collection=tickets&operation=insert");
Object result = template.requestBodyAndHeader("direct:insert", "irrelevantBody", MongoDbConstants.OPERATION_HEADER, "count");
assertTrue("Result is not of type Long", result instanceof Long);