Java MongoDB Driver upsert を実行する


Java で MongoDB に upsert を実行しようとしたら、
記述方法がわからず、小2時間程度悩んでしまいましたので、
記述方を記載します。

Java MongoDB Driver v2 か v3 かで記述は異なる。

v2

How to upsert with mongodb-java-driver - Stack Overflow

v2 の場合、 DBCollection#update(DBObject q, DBObject o, boolean upsert, boolean multi) を使用して、
upsertを実行するようです。 boolean upsert に true を指定すると、upsert になります。

v3

How to upsert document in MongoDB Java driver 3 - Stack Overflow

DBCollection#update(DBObject q, DBObject o, boolean upsert, boolean multi) もありますが、MongoClient#getDB(String databaseName) が非推奨になっており、
MongoClient#getDatabase(String databaseName) を使用して、
MongoCollection を取得する実装をしている場合、
MongoCollection#updateOne(Bson filter, Bson update, UpdateOptions updateOptions)
を使用して、upsert する形になります。

UpdateOptions#upsert(boolean upsert) に true を指定すると、upsert になります。

updateOne で [java.lang.IllegalArgumentException: Invalid BSON field name …] が発生する。

updateOneの Bson update パラメータには、
Update Operators — MongoDB Manual 3.2 を指定する必要があります。
通常のDocument を指定した場合、
[java.lang.IllegalArgumentException: Invalid BSON field name …] が発生します。

通常のDocument を指定する場合は、
MongoCollection#replaceOne(Bson filter, Bson update, UpdateOptions updateOptions)
を使用する必要があります。

通常のDocument と言いっているのは、Update Operators を使わないで通常のkey&value を設定する形式を指します。

    /**
     * replaceOne
     * データを1件 updateする ヒットしなければ、対象ドキュメントをinsertする
     *
     * @param filer
     * @param map
     * @retrun UpdateResult
     */
    protected UpdateResult replaceOne(@NonNull Bson filer, @NonNull Map<String, Object> map) {
        MongoCollection<org.bson.Document> coll = getCollection();
        UpdateOptions options = new UpdateOptions().upsert(true).bypassDocumentValidation(true);
        ConsoleLog.dump(map.toString());
        return coll.replaceOne(filer, new Document(map), options);
    }

以上です。

コメント