95.8. MongoDB 操作 - producer エンドポイント
95.8.1. クエリー操作
95.8.1.1. findById
この操作は、_id フィールドが IN メッセージ本文の内容と一致するコレクションから 1 つの要素のみを取得します。着信オブジェクトは、Bson
型と同等のものであれば何でもかまいません。http://bsonspec.org/spec.html および http://www.mongodb.org/display/DOCS/Java+Types を参照してください。
from("direct:findById") .to("mongodb:myDb?database=flights&collection=tickets&operation=findById") .to("mock:resultFindById");
デフォルトの _id は Mongo によって ObjectId
タイプとして扱われるため、適切に変換する必要がある場合があることに注意してください。
from("direct:findById") .convertBodyTo(ObjectId.class) .to("mongodb:myDb?database=flights&collection=tickets&operation=findById") .to("mock:resultFindById");
オプションのパラメーターをサポート
この操作は射影演算子をサポートしています。フィールドフィルターの指定 (プロジェクション) を参照。
95.8.1.2. findOneByQuery
MongoDB クエリーセレクターに一致するコレクションから最初の要素を取得します。CamelMongoDbCriteria
ヘッダーが設定されている場合、その値はクエリーセレクターとして使用されます。CamelMongoDbCriteria
ヘッダーが null の場合、IN メッセージ本文がクエリーセレクターとして使用されます。どちらの場合も、クエリーセレクターは Bson
型であるか、Bson
に変換可能である必要があります (たとえば、JSON 文字列または HashMap
)。詳細は、型変換を参照してください。
MongoDB ドライバーが提供する Filters
を使用して、クエリーセレクターを作成します。
95.8.1.3. クエリーセレクターを使用しない例 (コレクション内の最初のドキュメントを返します)
from("direct:findOneByQuery") .to("mongodb:myDb?database=flights&collection=tickets&operation=findOneByQuery") .to("mock:resultFindOneByQuery");
95.8.1.4. クエリーセレクターを使用した例 (コレクション内で最初に一致したドキュメントを返します):
from("direct:findOneByQuery") .setHeader(MongoDbConstants.CRITERIA, constant(Filters.eq("name", "Raul Kripalani"))) .to("mongodb:myDb?database=flights&collection=tickets&operation=findOneByQuery") .to("mock:resultFindOneByQuery");
オプションのパラメーターをサポート
この操作は、射影演算子とソート句をサポートしています。フィールドフィルター (射影) の指定、並べ替え句の指定を参照してください。
95.8.1.5. findAll
findAll
オペレーションは、クエリーに一致するすべてのドキュメントを返すか、まったく一致しないドキュメントを返します。この場合、コレクションに含まれるすべてのドキュメントが返されます。クエリーオブジェクトは CamelMongoDbCriteria
ヘッダーから抽出されます。CamelMongoDbCriteria ヘッダーが null の場合、クエリーオブジェクトは抽出されたメッセージ本文です。つまり、タイプ Bson
であるか、Bson
に変換可能である必要があります。JSON 文字列または Hashmap にすることができます。詳細は、型変換を参照してください。
95.8.1.5.1. クエリーセレクターを使用しない例 (コレクション内のすべてのドキュメントを返します)
from("direct:findAll") .to("mongodb:myDb?database=flights&collection=tickets&operation=findAll") .to("mock:resultFindAll");
95.8.1.5.2. クエリーセレクターを使用した例 (コレクション内の一致するすべてのドキュメントを返します)
from("direct:findAll") .setHeader(MongoDbConstants.CRITERIA, Filters.eq("name", "Raul Kripalani")) .to("mongodb:myDb?database=flights&collection=tickets&operation=findAll") .to("mock:resultFindAll");
ページングと効率的な検索は、次のヘッダーを介してサポートされています。
ヘッダーのキー | クイック定数 | 説明 (MongoDB API ドキュメントから抜粋) | 想定されるタイプ |
---|---|---|---|
|
| カーソルの先頭にある指定された数の要素を破棄します。 | int/Integer |
|
| 返される要素の数を制限します。 | int/Integer |
|
| 1 つのバッチで返される要素の数を制限します。通常、カーソルは結果オブジェクトのバッチをフェッチし、ローカルに保存します。batchSize が正の場合、取得されたオブジェクトの各バッチのサイズを表します。パフォーマンスを最適化し、データ転送を制限するように調整できます。batchSize が負の場合、最大バッチサイズ制限 (通常は 4MB) 内に収まる数のオブジェクトが返され、カーソルが閉じられます。たとえば、batchSize が -10 の場合、サーバーは最大 10 個のドキュメントを 4MB に収まる数だけ返し、カーソルを閉じます。この機能は、ドキュメントが最大サイズ内に収まる必要があるという点で limit() とは異なり、サーバー側でカーソルを閉じる要求を送信する必要がないことに注意してください。バッチサイズは、カーソルが反復された後でも変更できます。その場合、設定は次のバッチ取得に適用されます。 | int/Integer |
|
| allowDiskUse MongoDB フラグを設定します。これは、MongoDB Server 4.3.1 以降でサポートされています。このヘッダーを古い MongoDB サーバーバージョンで使用すると、クエリーが失敗する可能性があります。 | boolean/Boolean |
95.8.1.5.3. オプション outputType=MongoIterable とバッチサイズの例
from("direct:findAll") .setHeader(MongoDbConstants.BATCH_SIZE).constant(10) .setHeader(MongoDbConstants.CRITERIA, constant(Filters.eq("name", "Raul Kripalani"))) .to("mongodb:myDb?database=flights&collection=tickets&operation=findAll&outputType=MongoIterable") .to("mock:resultFindAll");
ページングを使用している場合、findAll
操作は次の OUT ヘッダーも返し、結果ページを反復処理できるようにします。
ヘッダーのキー | クイック定数 | 説明 (MongoDB API ドキュメントから抜粋) | データのタイプ |
---|---|---|---|
|
| クエリーに一致するオブジェクトの数。これは、制限/スキップを考慮していません。 | int/Integer |
|
| クエリーに一致するオブジェクトの数。これは、制限/スキップを考慮していません。 | int/Integer |
オプションのパラメーターをサポート
この操作は、射影演算子とソート句をサポートしています。フィールドフィルター (射影) の指定、並べ替え句の指定を参照してください。
95.8.1.6. count
コレクション内のオブジェクトの総数を返し、OUT メッセージ本文として Long を返します。
次の例では、"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);
クエリーを提供でき ますクエリーオブジェクトは CamelMongoDbCriteria
ヘッダーから抽出されます。CamelMongoDbCriteria ヘッダーが null の場合、クエリーオブジェクトは抽出されたメッセージ本文です。つまり、タイプ Bson
または Bson
に変換可能である必要があり、操作はこの条件に一致するドキュメントの量を返します。
Document query = ... Long count = template.requestBodyAndHeader("direct:count", query, MongoDbConstants.COLLECTION, "dynamicCollectionName");
95.8.1.7. フィールドフィルターの指定 (プロジェクション)
デフォルトでは、クエリー操作は、一致するオブジェクト全体を (すべてのフィールドとともに) 返します。ドキュメントが大きく、フィールドのサブセットのみを取得する必要がある場合は、関連する Bson
(または JSON 文字列、マップなどの Bson
に変換可能な型) を設定するだけで、すべてのクエリー操作でフィールドフィルターを指定できます。) CamelMongoDbFieldsProjection
ヘッダーの定数ショートカット: MongoDbConstants.FIELDS_PROJECTION
。
これは、MongoDB の Projections
を使用して Bson の作成を簡素化する例です。_id
と boringField
を除くすべてのフィールドを取得します。
// route: from("direct:findAll").to("mongodb: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("mongodb: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);
95.8.1.8. ソート句の指定
Bson の作成を簡素化するために、MongoDB の Sorts
を使用する特定のフィールドによるソートに基づいて、コレクションから最小/最大レコードを取得する必要があることがよくあります。_id
と boringField
を除くすべてのフィールドを取得します。
// route: from("direct:findAll").to("mongodb: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 ヘッダーも指定されている場合、操作は、別のコンポーネント (たとえば、パラメーター化された MyBatis SELECT クエリー) に直接渡すことができる単一のフィールド/値のペアを返します。この例では、コレクションから一時的に最新のドキュメントをフェッチし、結果を documentTimestamp
フィールドに基づいて 1 つのフィールドに削減する方法を示します。
.from("direct:someTriggeringEvent") .setHeader(MongoDbConstants.SORT_BY).constant(Sorts.descending("documentTimestamp")) .setHeader(MongoDbConstants.FIELDS_PROJECTION).constant(Projection.include("documentTimestamp")) .setBody().constant("{}") .to("mongodb:myDb?database=local&collection=myDemoCollection&operation=findOneByQuery") .to("direct:aMyBatisParameterizedSelect");
95.8.2. 操作の作成/更新
95.8.2.1. insert
IN メッセージ本文から取得した新しいオブジェクトを MongoDB コレクションに挿入します。Document
または List
に変換するために型変換が試行されます。
シングル挿入とマルチ挿入の 2 つのモードがサポートされています。複数の挿入の場合、エンドポイントは、Document であるか、Document
に変換できる限り、任意のタイプのオブジェクトのリスト、配列、またはコレクションを期待します。以下に例を示します。
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 が自動的に値を生成します。ただし、指定しても一意でない場合、挿入操作は失敗します (Camel が気付くには、invokeGetLastError を有効にするか、書き込み結果を待機する WriteConcern を設定する必要があります)。
これはコンポーネントの制限ではありませんが、MongoDB でより高いスループットを実現する方法です。カスタム _id
を使用している場合は、アプリケーションレベルで一意であることを確認する必要があります (これも良い方法です)。
挿入されたレコードの OID は、CamelMongoOid
キー (MongoDbConstants.OID
定数) の下のメッセージヘッダーに格納されます。保存される値は、単一の挿入の場合は org.bson.types.ObjectId
、複数のレコードが挿入された場合は java.util.List<org.bson.types.ObjectId>
です。
MongoDB Java Driver 3.x では、insertOne および insertMany オペレーションは void を返します。Camel 挿入操作は、挿入されたドキュメントまたはドキュメントのリストを返します。必要に応じて、各ドキュメントが新しい OID によって更新されることに注意してください。
95.8.2.2. save
保存操作は upsert (UPdate、inSERT) 操作と同等で、レコードが更新され、レコードが存在しない場合は挿入されます。これらはすべて 1 つのアトミック操作で行われます。MongoDB は _id
フィールドに基づいてマッチングを実行します。
更新の場合、オブジェクトは完全に置き換えられ、MongoDB の $modifiers の使用は許可されないことに注意してください。したがって、オブジェクトがすでに存在する場合にそのオブジェクトを操作する場合は、次の 2 つのオプションがあります。
- 最初にオブジェクト全体とそのすべてのフィールドを取得するためのクエリーを実行し (効率的でない場合があります)、Camel 内で変更してから保存します。
- $modifiers で更新操作を使用すると、代わりにサーバー側で更新が実行されます。upsert フラグを有効にできます。この場合、挿入が必要な場合、MongoDB は $modifiers をフィルタークエリーオブジェクトに適用し、結果を挿入します。
保存するドキュメントに _id
属性が含まれていない場合、操作は挿入になり、作成された新しい _id
が CamelMongoOid
ヘッダーに配置されます。
以下に例を示します。
from("direct:insert") .to("mongodb:myDb?database=flights&collection=tickets&operation=save");
// route: from("direct:insert").to("mongodb:myDb?database=flights&collection=tickets&operation=save"); org.bson.Document docForSave = new org.bson.Document(); docForSave.put("key", "value"); Object result = template.requestBody("direct:insert", docForSave);
95.8.2.3. update
コレクションの 1 つまたは複数のレコードを更新します。フィルタークエリーと更新ルールが必要です。
MongoDBConstants.CRITERIA ヘッダーを使用してフィルターを Bson
として定義し、更新ルールを本文で Bson
として定義できます。
エンリッチ後の更新Bson
として MongoDBConstants.CRITERIA ヘッダーを使用してフィルターを定義し、更新前に mongodb にクエリーを実行する際に、集約ストラテジーでエンリッチパターンを使用してから mongodb 更新を適用する場合に、集約中に結果の camel エクスチェンジからフィルターを削除する必要があることに注意してください。集約中にこのヘッダーを削除しない場合、および/または camel エクスチェンジを mongodb producer エンドポイントに送信する前に MongoDBConstants.CRITERIA ヘッダーを再定義しない場合、mongodb の更新中に無効な camel エクスチェンジペイロードが発生する可能性があります。
2 番目の方法は、正確に 2 つの要素を含む IN メッセージボディーとして List<Bson> を要求します。
- 要素 1 (インデックス 0) ⇒ フィルタークエリー ⇒ 通常のクエリーオブジェクトと同じように、影響を受けるオブジェクトを決定します
- 要素 2 (インデックス 1) ⇒ 更新ルール ⇒ 一致したオブジェクトがどのように更新されるか。MongoDB からのすべての 修飾子操作 がサポートされています。
Multiupdates
デフォルトでは、MongoDB は、複数のオブジェクトがフィルタークエリーに一致する場合でも、1 つのオブジェクトのみを更新します。一致する すべての レコードを更新するように MongoDB に指示するには、CamelMongoDbMultiUpdate
IN メッセージヘッダーを true
に設定します。
キー CamelMongoDbRecordsAffected
を持つヘッダーが返されます (MongoDbConstants.RECORDS_AFFECTED
定数) 更新されたレコードの数 (WriteResult.getN()
からコピーされます)。
次の IN メッセージヘッダーをサポートします。
ヘッダーのキー | クイック定数 | 説明 (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"); List<Bson> body = new ArrayList<>(); Bson filterField = Filters.eq("filterField", true); body.add(filterField); BsonDocument updateObj = new BsonDocument().append("$set", new BsonDocument("scientist", new BsonString("Darwin"))); body.add(updateObj); Object result = template.requestBodyAndHeader("direct:update", body, MongoDbConstants.MULTIUPDATE, true);
// route: from("direct:update").to("mongodb:myDb?database=science&collection=notableScientists&operation=update"); Maps<String, Object> headers = new HashMap<>(2); headers.add(MongoDbConstants.MULTIUPDATE, true); headers.add(MongoDbConstants.FIELDS_FILTER, Filters.eq("filterField", true)); String updateObj = Updates.set("scientist", "Darwin");; Object result = template.requestBodyAndHeaders("direct:update", updateObj, headers);
// route: from("direct:update").to("mongodb:myDb?database=science&collection=notableScientists&operation=update"); String updateObj = "[{\"filterField\": true}, {\"$set\", {\"scientist\", \"Darwin\"}}]"; Object result = template.requestBodyAndHeader("direct:update", updateObj, MongoDbConstants.MULTIUPDATE, true);
95.8.3. 操作の削除
95.8.3.1. remove
コレクションから一致するレコードを削除します。IN メッセージ本文は、削除フィルタークエリーとして機能し、DBObject
タイプまたはそれに変換可能なタイプであることが期待されます。
次の例では、科学データベースの notableScientists コレクションで、フィールド 'conditionField' が true に等しいすべてのオブジェクトを削除します。
// route: from("direct:remove").to("mongodb:myDb?database=science&collection=notableScientists&operation=remove"); Bson conditionField = Filters.eq("conditionField", true); Object result = template.requestBody("direct:remove", conditionField);
キー CamelMongoDbRecordsAffected
を持つヘッダーが返されます (MongoDbConstants.RECORDS_AFFECTED
定数)。タイプは int
で、削除された (WriteResult.getN()
からコピーされた) レコードの数を含みます。
95.8.4. 一括書き込み操作
95.8.4.1. bulkWrite
実行順序を制御して書き込み操作を一括で実行します。挿入、更新、および削除操作のコマンドを含む IN メッセージ本文として List<WriteModel<Document>>
が必要です。
次の例では、新しい科学者 "Pierre Curie" を挿入し、"scientist" フィールドの値を "Marie Curie" に設定して ID "5" のレコードを更新し、ID "3" のレコードを削除します。
// route: from("direct:bulkWrite").to("mongodb:myDb?database=science&collection=notableScientists&operation=bulkWrite"); List<WriteModel<Document>> bulkOperations = Arrays.asList( new InsertOneModel<>(new Document("scientist", "Pierre Curie")), new UpdateOneModel<>(new Document("_id", "5"), new Document("$set", new Document("scientist", "Marie Curie"))), new DeleteOneModel<>(new Document("_id", "3"))); BulkWriteResult result = template.requestBody("direct:bulkWrite", bulkOperations, BulkWriteResult.class);
デフォルトでは、操作は順番に実行され、最初の書き込みエラーで中断され、リスト内の残りの書き込み操作は処理されません。リスト内の残りの書き込み操作の処理を続行するように MongoDB に指示するには、CamelMongoDbBulkOrdered
IN メッセージヘッダーを false
に設定します。順序付けされていない操作は並行して実行され、この動作は保証されません。
ヘッダーのキー | クイック定数 | 説明 (MongoDB API ドキュメントから抜粋) | 想定されるタイプ |
---|---|---|---|
|
| 順序付きまたは順序なしの操作実行を実行します。デフォルトは true です。 | boolean/Boolean |
95.8.5. その他の操作
95.8.5.1. aggregate
本文に含まれる特定のパイプラインを使用して集計を実行します。集約は、長く重い操作になる可能性があります。注意して使用してください。
// route: from("direct:aggregate").to("mongodb:myDb?database=science&collection=notableScientists&operation=aggregate"); List<Bson> aggregate = Arrays.asList(match(or(eq("scientist", "Darwin"), eq("scientist", group("$scientist", sum("count", 1))); from("direct:aggregate") .setBody().constant(aggregate) .to("mongodb:myDb?database=science&collection=notableScientists&operation=aggregate") .to("mock:resultAggregate");
次の IN メッセージヘッダーをサポートします。
ヘッダーのキー | クイック定数 | 説明 (MongoDB API ドキュメントから抜粋) | 想定されるタイプ |
---|---|---|---|
|
| バッチごとに返すドキュメントの数を設定します。 | int/Integer |
|
| 集約パイプラインステージを有効にして、データを一時ファイルに書き込みます。 | boolean/Boolean |
デフォルトでは、すべての結果のリストが返されます。結果のサイズによっては、これはメモリーを大量に消費する可能性があります。より安全な代替手段は、outputType=MongoIterable を設定することです。次の Processor は、メッセージ本文に iterable を表示し、結果を 1 つずつ処理できるようにします。したがって、バッチサイズを設定して iterable を返すと、結果の効率的な取得と処理が可能になります。
例は次のようになります。
List<Bson> aggregate = Arrays.asList(match(or(eq("scientist", "Darwin"), eq("scientist", group("$scientist", sum("count", 1))); from("direct:aggregate") .setHeader(MongoDbConstants.BATCH_SIZE).constant(10) .setBody().constant(aggregate) .to("mongodb:myDb?database=science&collection=notableScientists&operation=aggregate&outputType=MongoIterable") .split(body()) .streaming() .to("mock:resultAggregate");
.split (body ())
を呼び出すだけでエントリーを 1 つずつルートに送信できますが、最初にすべてのエントリーをメモリーにロードすることに注意してください。したがって、データをバッチでメモリーにロードするには、.streaming()
を呼び出す必要があります。
95.8.5.2. getDbStats
MongoDB シェルで db.stats()
コマンドを実行するのと同じです。これは、データベースに関する有用な統計値を表示します。
以下に例を示します。
> db.stats(); { "db" : "test", "collections" : 7, "objects" : 719, "avgObjSize" : 59.73296244784423, "dataSize" : 42948, "storageSize" : 1000058880, "numExtents" : 9, "indexes" : 4, "indexSize" : 32704, "fileSize" : 1275068416, "nsSizeMB" : 16, "ok" : 1 }
使用例:
// 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 Document", result instanceof Document);
この操作は、シェルに表示されるものと同様のデータ構造を、OUT メッセージ本文の Document
の形式で返します。
95.8.5.3. getColStats
コレクションに関する有用な統計値を表示する、MongoDB シェルで db.collection.stats()
コマンドを実行するのと同じです。
以下に例を示します。
> db.camelTest.stats(); { "ns" : "test.camelTest", "count" : 100, "size" : 5792, "avgObjSize" : 57.92, "storageSize" : 20480, "numExtents" : 2, "nindexes" : 1, "lastExtentSize" : 16384, "paddingFactor" : 1, "flags" : 1, "totalIndexSize" : 8176, "indexSizes" : { "_id_" : 8176 }, "ok" : 1 }
使用例:
// 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 Document", result instanceof Document);
この操作は、シェルに表示されるものと同様のデータ構造を、OUT メッセージ本文の Document
の形式で返します。
95.8.5.4. command
データベースで本体をコマンドとして実行します。ホスト情報、レプリケーション、またはシャーディングステータスを取得するなどの管理操作に役立ちます。
コレクションパラメーターは、この操作では使用されません。
// route: from("command").to("mongodb:myDb?database=science&operation=command"); DBObject commandBody = new BasicDBObject("hostInfo", "1"); Object result = template.requestBody("direct:command", commandBody);
95.8.6. 動的操作
エクスチェンジは、MongoDbConstants.OPERATION_HEADER
定数で定義された CamelMongoDbOperation
ヘッダーを設定することにより、エンドポイントの固定操作をオーバーライドできます。
サポートされる値は、MongoDbOperation 列挙によって決定され、エンドポイント 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);