Spring-Data-Mongo を使用して、Java アプリケーションから MongoDB にアクセスしています。一般に、すべて正常に動作しますが、奇妙な動作が 1 つあります。
Java コードでリポジトリを初期化するとき、ensureIndex を使用してコレクションにインデックスを作成します。単体テストでは、コレクションからすべてのインデックスを IndexInfo オブジェクトとして読み取り、これらの IndexInfo オブジェクトにインデックスを作成するフィールドがメンバー indexFields に含まれているかどうかを確認します。これは、すべてをセットアップしたときにもうまくいきました。
本番環境でインデックスの 1 つを再作成する必要が生じたので、それを削除し、Mongo シェルを使用して再度作成しました。システムは正常に動作しているようで、問題は発生しませんでした。一貫性の理由から、同じ方法でテスト環境とローカル環境にも同じ変更を加えました。その後、indexField メンバーが空になったため、インデックス チェックの単体テストが失敗することに気付きました。
想像できることはすべて試しましたが、Mongo シェルを使用してインデックスを作成するとすぐに、同一の構成でインデックスを作成しても、Spring はインデックス フィールドを提供しなくなります。
なぜそれが起こるのか、それが問題があることを示しているのか、誰か教えてもらえますか? コレクションを削除せずにこれを修正する方法はありますか? 次の本番リリース後にインデックスを削除してから、挿入をトリガーすることを考えていました。私のローカル マシンでは、予想どおりにインデックスが作成され、テストは成功しました。
- - 追加情報 - - -
こんにちはトリシャ、
すぐに対応できなくて申し訳ありませんが、このための小さな単体テストを作成する時間ができました。
空のデータベースで次のテストを実行すると、正常に動作します。
@Test
public void testIndexing() throws Exception {
this.mongoTemplate.indexOps("testcollection").ensureIndex(
new Index().on("indexfield", Order.ASCENDING).unique().sparse());
List<IndexInfo> indexInfos = mongoTemplate.indexOps("testcollection").getIndexInfo();
assertEquals("We want two indexes, id and indexfield", 2, indexInfos.size());
for (IndexInfo info : indexInfos) {
assertEquals("All indexes are only meant to have one field", 1, info.getIndexFields().size());
if (info.getName().startsWith("indexfield")) {
assertTrue("Unexpected index field", info.isIndexForFields(Arrays.asList(new String[]{ "indexfield" })));
assertTrue("Index indexfield must be unique", info.isUnique());
assertTrue("Index indexfield must be sparse", info.isSparse());
assertFalse("Index indexfield must not be droping duplicates", info.isDropDuplicates());
} else if (!"_id_".equals(info.getName())) {
fail("Unexpected index: '" + info.getName() + "'");
}
}
}
次に、mongo シェルを開き、次のように呼び出します。
db.testcollection.dropIndexes();
db.testcollection.ensureIndex({"indexfield":1}, {"unique":true, "sparse":true})
2 番目の呼び出しは、Java コードとまったく同じインデックスを作成する必要があります。テストを再度実行すると、インデックスが既に存在するため (そうあるべきだと思います)、ensureIndex-Method は何もしませんが、インデックス フィールドのアサートでテストは失敗します。インデックス情報があるため、最初のアサートは正常に機能します。
mongo シェルでインデックスをチェックすると、インデックスがシェル経由で作成されたか、Java コード経由で作成されたかに関係なく、同じ出力が生成されますが、インデックスがシェル経由で作成された場合、スプリングは何らかの理由でインデックス フィールドを取得しません。
これについてヒントをいただければ、本当に助かります。