230.6. MongoDB operations - producer 端点
230.6.1. 查询操作 复制链接链接已复制到粘贴板!
230.6.1.1. findById 复制链接链接已复制到粘贴板!
此操作仅从与 IN 消息正文的内容匹配的集合中检索一个元素。传入的对象可以是等同于 Bson
类型的任何对象。请参阅 http://bsonspec.org//specification[http://bsonspec.org//specification] 和 http://www.mongodb.org/display/DOCS/Java+Types。
from("direct:findById") .to("mongodb3:myDb?database=flights&collection=tickets&operation=findById") .to("mock:resultFindById");
from("direct:findById")
.to("mongodb3:myDb?database=flights&collection=tickets&operation=findById")
.to("mock:resultFindById");
支持可选参数。此操作支持指定字段过滤器。请参阅 指定可选参数。
230.6.1.2. findOneByQuery 复制链接链接已复制到粘贴板!
使用此操作只从与 MongoDB 查询匹配的集合中检索一个元素(第一个)。查询对象提取 CamelMongoDbCriteria
标头。如果 CamelMongoDbCriteria 标头为 null,则查询对象被提取消息正文,即 Bson
类型或可转换为 Bson
。它可以是 JSON 字符串或 Hashmap。如需更多信息,请参阅 #Type 转换。您可以使用 MongoDB Driver 中的 Filters 类。
无查询的示例(返回集合的任何对象):
from("direct:findOneByQuery") .to("mongodb3:myDb?database=flights&collection=tickets&operation=findOneByQuery") .to("mock:resultFindOneByQuery");
from("direct:findOneByQuery")
.to("mongodb3:myDb?database=flights&collection=tickets&operation=findOneByQuery")
.to("mock:resultFindOneByQuery");
带有查询的示例(返回一个匹配结果):
from("direct:findOneByQuery") .setHeader(MongoDbConstants.CRITERIA, Filters.eq("name", "Raul Kripalani")) .to("mongodb3:myDb?database=flights&collection=tickets&operation=findOneByQuery") .to("mock:resultFindOneByQuery");
from("direct:findOneByQuery")
.setHeader(MongoDbConstants.CRITERIA, Filters.eq("name", "Raul Kripalani"))
.to("mongodb3:myDb?database=flights&collection=tickets&operation=findOneByQuery")
.to("mock:resultFindOneByQuery");
支持可选参数。此操作支持指定字段 projection 和/或 sort 子句。请参阅 指定可选参数。
230.6.1.3. findAll 复制链接链接已复制到粘贴板!
findAll
操作会返回与查询匹配的所有文档,或者根本没有返回集合中包含的所有文档。查询对象提取 CamelMongoDbCriteria
标头。如果 CamelMongoDbCriteria 标头为 null,则查询对象被提取消息正文,即 Bson
类型或可转换为 Bson
。它可以是 JSON 字符串或 Hashmap。如需更多信息,请参阅 #Type 转换。
无查询的示例(重新返回集合中的所有对象):
from("direct:findAll") .to("mongodb3:myDb?database=flights&collection=tickets&operation=findAll") .to("mock:resultFindAll");
from("direct:findAll")
.to("mongodb3:myDb?database=flights&collection=tickets&operation=findAll")
.to("mock:resultFindAll");
带有查询的示例(返回所有匹配结果):
from("direct:findAll") .setHeader(MongoDbConstants.CRITERIA, Filters.eq("name", "Raul Kripalani")) .to("mongodb3:myDb?database=flights&collection=tickets&operation=findAll") .to("mock:resultFindAll");
from("direct:findAll")
.setHeader(MongoDbConstants.CRITERIA, Filters.eq("name", "Raul Kripalani"))
.to("mongodb3: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=MongoIterable 和 batch size 的示例:
from("direct:findAll") .setHeader(MongoDbConstants.BATCH_SIZE).constant(10) .setHeader(MongoDbConstants.CRITERIA, Filters.eq("name", "Raul Kripalani")) .to("mongodb3:myDb?database=flights&collection=tickets&operation=findAll&outputType=MongoIterable") .to("mock:resultFindAll");
from("direct:findAll")
.setHeader(MongoDbConstants.BATCH_SIZE).constant(10)
.setHeader(MongoDbConstants.CRITERIA, Filters.eq("name", "Raul Kripalani"))
.to("mongodb3:myDb?database=flights&collection=tickets&operation=findAll&outputType=MongoIterable")
.to("mock:resultFindAll");
findAll
操作还会返回以下 OUT 标头,以便在使用分页时迭代结果页面:
标头键 | 快速常量 | 描述(从 MongoDB API 文档中提取) | 数据类型 |
---|---|---|---|
|
| 与查询匹配的对象数量。这不会考虑 limit/skip。 | int/Integer |
|
| 与查询匹配的对象数量。这不会考虑 limit/skip。 | int/Integer |
支持可选参数。此操作支持指定字段 projection 和/或 sort 子句。请参阅 指定可选参数。
230.6.1.4. æ•°é‡� 复制链接链接已复制到粘贴板!
返回集合中对象总数,返回 Long 作为 OUT 消息正文。
以下示例将计算 "dynamicCollectionName" 集合中记录的数量。注意如何启用动态性,因此操作不会针对"notableScientists"集合运行,而是针对"dynamicCollectionName"集合运行。
// from("direct:count").to("mongodb3: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("mongodb3: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);
您可以提供 查询对象提取 CamelMongoDbCriteria
标头。如果 CamelMongoDbCriteria 标头为 null,则查询对象被提取的消息正文,即
或 convertable to Bson。
Bson
Document query = ... Long count = template.requestBodyAndHeader("direct:count", query, MongoDbConstants.COLLECTION, "dynamicCollectionName");
Document query = ...
Long count = template.requestBodyAndHeader("direct:count", query, MongoDbConstants.COLLECTION, "dynamicCollectionName");
230.6.1.5. 指定字段过滤器(项目) 复制链接链接已复制到粘贴板!
默认情况下,查询操作将在其整个中返回匹配的对象(及其所有字段)。如果您的文档非常大,且您只需要检索其字段的子集,您可以在所有查询操作中指定字段过滤器,只需通过设置相关的 Bson
(或 typeible to Bson
,如 JSON String、Map 等)在 CamelMongoDbFieldsProjection
标头中指定字段过滤器。
以下是一个示例,它使用 MongoDB 的 Projections
来简化 Bson 的创建。它检索除 _id
和 boringField
以外的所有字段:
// route: from("direct:findAll").to("mongodb3:myDb?database=flights&collection=tickets&operation=findAll") Bson fieldProjection = Projection.exclude("_id", "boringField"); Object result = template.requestBodyAndHeader("direct:findAll", ObjectUtils.NULL, MongoDbConstants.FIELDS_PROJECTION, fieldProjection);
// route: from("direct:findAll").to("mongodb3:myDb?database=flights&collection=tickets&operation=findAll")
Bson fieldProjection = Projection.exclude("_id", "boringField");
Object result = template.requestBodyAndHeader("direct:findAll", ObjectUtils.NULL, MongoDbConstants.FIELDS_PROJECTION, fieldProjection);
以下是一个示例,它使用 MongoDB 的 Projections
来简化 Bson 的创建。它检索除 _id
和 boringField
以外的所有字段:
// route: from("direct:findAll").to("mongodb3:myDb?database=flights&collection=tickets&operation=findAll") Bson fieldProjection = Projection.exclude("_id", "boringField"); Object result = template.requestBodyAndHeader("direct:findAll", ObjectUtils.NULL, MongoDbConstants.FIELDS_PROJECTION, fieldProjection);
// route: from("direct:findAll").to("mongodb3:myDb?database=flights&collection=tickets&operation=findAll")
Bson fieldProjection = Projection.exclude("_id", "boringField");
Object result = template.requestBodyAndHeader("direct:findAll", ObjectUtils.NULL, MongoDbConstants.FIELDS_PROJECTION, fieldProjection);
230.6.1.6. 指定 sort 子句 复制链接链接已复制到粘贴板!
通常,根据特定字段排序从集合中获取 min/max 记录的要求,该字段使用 MongoDB 的 排序来简化 Bs
on 的创建。它检索除 _id
和 boringField
以外的所有字段:
// route: from("direct:findAll").to("mongodb3:myDb?database=flights&collection=tickets&operation=findAll") Bson sorts = Sorts.descending("_id"); Object result = template.requestBodyAndHeader("direct:findAll", ObjectUtils.NULL, MongoDbConstants.SORT_BY, sorts);
// route: from("direct:findAll").to("mongodb3:myDb?database=flights&collection=tickets&operation=findAll")
Bson sorts = Sorts.descending("_id");
Object result = template.requestBodyAndHeader("direct:findAll", ObjectUtils.NULL, MongoDbConstants.SORT_BY, sorts);
在 Camel 路由中,SORT_BY 标头可用于 findOneByQuery 操作,以实现相同的结果。如果还指定了 FIELDS_PROJECTION 标头,则操作将返回单个字段/值对,可直接传递给另一个组件(例如,参数ized MyBatis SELECT 查询)。本例演示了如何根据 documentTimestamp
字段从集合中获取临时最新的文档,并将结果减少到单个字段:
230.6.2. 创建/更新操作 复制链接链接已复制到粘贴板!
230.6.2.1. insert 复制链接链接已复制到粘贴板!
将新对象插入到 MongoDB 集合中,从 IN 消息正文获取。试图将类型转换转换为 文档或
列表
。
支持两种模式:单一插入和多个插入。对于多个插入,端点将预期任意类型的对象列表、数组或集合,只要它们是 - 或可以转换为 - 文档
。Example:
from("direct:insert") .to("mongodb3:myDb?database=flights&collection=tickets&operation=insert");
from("direct:insert")
.to("mongodb3:myDb?database=flights&collection=tickets&operation=insert");
该操作将返回 WriteResult,具体取决于 WriteConcern
或 invokeGetLastError
选项的值,getLastError ()
将被调用。如果您希望访问些操作的最终结果,可以通过在 WriteResult
上调用 getLastError()
或 getCachedLastError()
来获取 CommandResult
。然后,您可以通过调用 CommandResult.ok ()
, CommandResult.getErrorMessage ()
and/or CommandResult.getException ()
来验证结果。
请注意,新对象的 _id
在集合中必须是唯一的。如果没有指定值,MongoDB 将自动为您生成一个值。但是,如果您确实指定了它,则插入操作将失败(对于 Camel 需要注意,您需要启用 invokeGetLastError 或设置等待写结果的 WriteConcern)。
这并不是组件的限制,而是在 MongoDB 中的工作方式以获得更高的吞吐量。如果您使用自定义 _id
,您预期在应用程序级别确保是唯一的(这也是很好的做法)。
插入记录的 OID 存储在 CamelMongoOid
键下的消息标头中(MongoDbConstants.OID
constant)。存储的值为 org.bson.types.ObjectId
,用于单个插入或 java.util.List<org.bson.types.ObjectId>
; (如果插入多个记录)。
在 MongoDB Java Driver 3.x 中,insertOne 和 insertMany 操作返回 void。Camel 插入操作会返回插入的 Documents 或 Documents 列表。请注意,如果需要,每个文档都由一个新的 OID 更新。
230.6.2.2. save 复制链接链接已复制到粘贴板!
save 操作等同于 upsert (UPdate,inSERT)操作,其中将更新记录,如果不存在,它将被插入一个原子操作。MongoDB 将根据 _id
字段执行匹配。
请注意,如果更新,对象会被完全被替换,而不允许使用 MongoDB 的 $modifier。因此,如果要操作对象已存在,则有两个选项:
- 执行查询以首先检索整个对象及其所有字段(或者效率不高),在 Camel 中更改它,然后保存它。
- 使用带有 $modifiers 的 update 操作,这将在服务器端执行更新。您可以启用 upsert 标志,在这种情况下,如果需要插入,MongoDB 会将 $modifiers 应用到过滤器查询对象并插入结果。
如果要保存的文档不包含 _id
属性,则操作将是插入的,并且创建新的 _id
将放在 CamelMongoOid
标头中。
例如:
from("direct:insert") .to("mongodb3:myDb?database=flights&collection=tickets&operation=save");
from("direct:insert")
.to("mongodb3:myDb?database=flights&collection=tickets&operation=save");
230.6.2.3. update 复制链接链接已复制到粘贴板!
更新集合上的一个或多个记录。需要过滤器查询和更新规则。
您可以使用 MongoDBConstants.CRITERIA 标头定义为 Bson
,并在 Body 中将更新规则定义为 Bson
。
增强后更新 .当使用 MongoDBConstants.CRITERIA 标头作为 Bson
定义过滤器时,在更新前查询 mongodb,您应该注意,如果您在聚合中使用带有聚合策略,则需要在聚合过程中将其从生成的 camel Exchange 中删除,然后应用 mongodb 更新。如果您在聚合和/或重新定义 MongoDBConstants.CRITERIA 标头前没有删除这个标头,在将 camel Exchange 发送到 mongodb producer 端点前,您可能会在更新 mongodb 时最终使用无效的 camel Exchange payload。
第二种方法 Require a List<Bson> 作为 IN message body contains exactly 2 项:
- 元素 1 (index 0) jpeg 过滤器查询 TOKEN 确定受影响的对象,与典型的查询对象相同
- 元素 2 (index 1) TOKEN 更新规则 jpeg 如何更新匹配的对象。支持 MongoDB 中的所有 修饰符操作。
多更新 .默认情况下,MongoDB 只会更新 1 个对象,即使多个对象与过滤器查询匹配。要指示 MongoDB 更新 所有匹配 记录,请将 CamelMongoDbMultiUpdate
IN 消息标头设置为 true
。
将返回一个带有键 CamelMongoDbRecordsAffected
的标头(MongoDbConstants.RECORDS_AFFECTED
constant),其记录数量已更新(从 WriteResult.getN ()
)。
支持以下 IN 消息标头:
标头键 | 快速常量 | 描述(从 MongoDB API 文档中提取) | 预期类型 |
---|---|---|---|
|
| 如果更新应该应用到所有匹配的对象。请参阅 http://www.mongodb.org/display/DOCS/Atomic+Operations | 布尔值/布尔值 |
|
| 如果数据库应该创建元素(如果不存在) | 布尔值/布尔值 |
例如,以下命令将 "scientist" 字段的值设置为 "Darwin" 来更新其 filterField 字段等于 true 的所有记录:
// route: from("direct:update").to("mongodb3:myDb?database=science&collection=notableScientists&operation=update"); Bson filterField = Filters.eq("filterField", true); String updateObj = Updates.set("scientist", "Darwin"); Object result = template.requestBodyAndHeader("direct:update", new Bson[] {filterField, Document.parse(updateObj)}, MongoDbConstants.MULTIUPDATE, true);
// route: from("direct:update").to("mongodb3:myDb?database=science&collection=notableScientists&operation=update");
Bson filterField = Filters.eq("filterField", true);
String updateObj = Updates.set("scientist", "Darwin");
Object result = template.requestBodyAndHeader("direct:update", new Bson[] {filterField, Document.parse(updateObj)}, MongoDbConstants.MULTIUPDATE, true);
// route: from("direct:update").to("mongodb3:myDb?database=science&collection=notableScientists&operation=update"); String updateObj = "[{\"filterField\": true}, {\"$set\", {\"scientist\", \"Darwin\"}}]"; Object result = template.requestBodyAndHeader("direct:update", updateObj, MongoDbConstants.MULTIUPDATE, true);
// route: from("direct:update").to("mongodb3:myDb?database=science&collection=notableScientists&operation=update");
String updateObj = "[{\"filterField\": true}, {\"$set\", {\"scientist\", \"Darwin\"}}]";
Object result = template.requestBodyAndHeader("direct:update", updateObj, MongoDbConstants.MULTIUPDATE, true);
230.6.3. 删除操作 复制链接链接已复制到粘贴板!
230.6.3.1. remove 复制链接链接已复制到粘贴板!
从集合中删除匹配的记录。IN 消息正文将充当删除过滤器查询,它预期为 DBObject
类型或可转换的类型。
以下示例将删除在 Science 数据库, notableScientists 集合中,其字段 'conditionField' 等于 true 的所有对象:
// route: from("direct:remove").to("mongodb3:myDb?database=science&collection=notableScientists&operation=remove"); Bson conditionField = Filters.eq("conditionField", true); Object result = template.requestBody("direct:remove", conditionField);
// route: from("direct:remove").to("mongodb3:myDb?database=science&collection=notableScientists&operation=remove");
Bson conditionField = Filters.eq("conditionField", true);
Object result = template.requestBody("direct:remove", conditionField);
返回一个带有键 CamelMongoDbRecordsAffected
的标头 (MongoDbConstants.RECORDS_AFFECTED
constant) with type int
, 包括删除记录的数量 (从 WriteResult.getN()
复制)。
230.6.4. 批量写操作 复制链接链接已复制到粘贴板!
230.6.4.1. bulkWrite 复制链接链接已复制到粘贴板!
从 Camel 2.21 开始提供
批量执行写入操作,并控制执行顺序。需要 List<WriteModel<Document
>> 作为 IN 消息正文,其中包含用于插入、更新和删除操作的命令。
以下示例将插入一个新的科学家 "Pierre Curie",更新 id 为 "5" 的记录,将 "scientist" 项的值设置为 "Marie Curie" 并删除 id 为 "3" 的记录 :
默认情况下,操作会按顺序执行,并在第一个写入错误上中断,而不处理列表中任何剩余的写入操作。要指示 MongoDB 继续处理列表中剩余的写入操作,请将 CamelMongoDbBulkOrdered
IN 消息标头设置为 false
。未排序的操作是并行执行的,无法保证此行为。
标头键 | 快速常量 | 描述(从 MongoDB API 文档中提取) | 预期类型 |
---|---|---|---|
|
| 执行有序或未排序的操作执行。默认值为 true。 | 布尔值/布尔值 |
230.6.5. 其他操作 复制链接链接已复制到粘贴板!
230.6.5.1. 聚合 复制链接链接已复制到粘贴板!
使用正文中包含的给定管道执行聚合。聚合可能非常长且繁重的操作。请谨慎使用。
支持以下 IN 消息标头:
标头键 | 快速常量 | 描述(从 MongoDB API 文档中提取) | 预期类型 |
---|---|---|---|
|
| 设置每个批处理要返回的文档数量。 | int/Integer |
|
| 启用聚合管道阶段,将数据写入临时文件。 | 布尔值/布尔值 |
默认情况下,返回所有结果的列表。根据结果的大小,这在内存上可能很重。一个安全的替代方案是设置 outputType=MongoIterable。下一个处理器将在消息正文中看到可迭代的结果,以便它逐一完成结果。因此,设置批处理大小并返回一个可迭代功能,以便有效地检索和处理结果。
您还可以通过包含 outputType=DBCursor (Camel 2.21+)作为端点选项,它比设置上述标头来"流"文档到您的路由。这您的交换来自 Mongo 驱动程序的 Exchange DBCursor 就像您在 Mongo shell 中执行 aggregate ()一样,您的路由可以迭代结果。默认情况下,如果没有这个选项,此组件将从驱动程序的光标中将文档加载到列表,并返回到您的路由 - 这可能会导致大量内存对象。请记住,在 DBCursor 时,不会要求提供匹配的文档数量 - 详情请查看 MongoDB 文档站点。
选项 outputType=MongoIterable 和 batch size 的示例:
请注意,调用 .split (body ())
足以发送路由一对条目,但仍然会首先将所有条目加载到内存中。因此,需要调用 .streaming ()
来通过批处理将数据加载到内存中。
230.6.5.2. getDbStats 复制链接链接已复制到粘贴板!
等同于在 MongoDB shell 中运行 db.stats ()
命令,该命令显示有关数据库的有用统计图。
例如:
使用示例:
// from("direct:getDbStats").to("mongodb3:myDb?database=flights&collection=tickets&operation=getDbStats"); Object result = template.requestBody("direct:getDbStats", "irrelevantBody"); assertTrue("Result is not of type Document", result instanceof Document);
// from("direct:getDbStats").to("mongodb3:myDb?database=flights&collection=tickets&operation=getDbStats");
Object result = template.requestBody("direct:getDbStats", "irrelevantBody");
assertTrue("Result is not of type Document", result instanceof Document);
该操作将返回与 shell 中显示的数据结构,格式为 OUT 消息正文中的 Document
形式。
230.6.5.3. getColStats 复制链接链接已复制到粘贴板!
等同于在 MongoDB shell 中运行 db.collection.stats ()
命令,该命令显示有关集合的有用统计图。
例如:
使用示例:
// from("direct:getColStats").to("mongodb3:myDb?database=flights&collection=tickets&operation=getColStats"); Object result = template.requestBody("direct:getColStats", "irrelevantBody"); assertTrue("Result is not of type Document", result instanceof Document);
// from("direct:getColStats").to("mongodb3:myDb?database=flights&collection=tickets&operation=getColStats");
Object result = template.requestBody("direct:getColStats", "irrelevantBody");
assertTrue("Result is not of type Document", result instanceof Document);
该操作将返回与 shell 中显示的数据结构,格式为 OUT 消息正文中的 Document
形式。
230.6.5.4. 命令 复制链接链接已复制到粘贴板!
作为命令在数据库上运行正文。Usefull for admin 操作作为获取主机信息、复制或分片状态。
这个操作不使用 collection 参数。
// route: from("command").to("mongodb3:myDb?database=science&operation=command"); DBObject commandBody = new BasicDBObject("hostInfo", "1"); Object result = template.requestBody("direct:command", commandBody);
// route: from("command").to("mongodb3:myDb?database=science&operation=command");
DBObject commandBody = new BasicDBObject("hostInfo", "1");
Object result = template.requestBody("direct:command", commandBody);
230.6.6. 动态操作 复制链接链接已复制到粘贴板!
Exchange 可以通过设置由 MongoDbConstants.OPERATION_HEADER
常数定义的 CamelMongoDbOperation
标头来覆盖端点的固定操作。
支持的值由 MongoDbOperation enumeration 决定,并与端点 URI 上的 operation
参数接受的值匹配。
例如:
// from("direct:insert").to("mongodb3: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("mongodb3: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);