2015-06-03 2 views
9

Что такое идиоматический способ ускорить документ, используя версию 3 java-драйвера mongodb (в частности, v3.0.1)?Как обновить документ в Java-драйвере MongoDB 3

У нас есть коллекция для сеансов и когда новый сеанс создается или модифицируется, мы хотим его активировать за одну операцию - вместо того, чтобы запрашивать, существует ли документ, а затем либо вставлять, либо заменять.

Наш старый код перестройки использовался scala driver casbah 2.7.3. Это выглядело как:

import com.mongodb.casbah.MongoCollection 
import com.mongdb.DBObject 
val sessionCollection: MongoCollection = ... 
val sessionKey: String = ... 
val sessionDocument: DBObject = ... // Either create a new one, or find and modify an existing one 

sessionCollection.update(
    "_id" -> sessionKey, 
    sessionDocument 
    upsert = true 
) 

В нашем проекте мы просто используя обычный драйвер Java 3.0.1 и мы используем BsonDocument вместо DBObject, чтобы сделать его более typsafe. Я пытался заменить выше что-то вроде:

import com.mongodb.client.MongoCollection 
val sessionCollection: MongoCollection = ... 
val sessionKey: String = ... 
val sessionDocument: BsonDocument = // Either create a new one, or find and modify an existing one 

val updateOptions = new UpdateOptions 
updateOptions.upsert(true) 

sessionCollection.updateOne(
    "_id" -> new BsonString(sessionKey), 
    sessionDocument, 
    updateOptions 
) 

Это бросает ошибку «java.lang.IllegalArgumentException: Invalid имя BSON поля ...». Ошибка указана в this question, но операционная система в этом вопросе не пыталась активировать одну операцию - они использовали контекст, чтобы решить, следует ли заменять/обновлять/вставлять и т. Д.

Я доволен образцами кода в scala или java.

Спасибо!

ответ

11

В серии драйверов Mongo Java Driver 3.0 мы добавили новый Crud API, который более ясен и, следовательно, является новичком. Эта инициатива была развернута во многих драйверах MongoDB, но она содержит некоторые изменения по сравнению с более старым API.

Поскольку вы не обновляете существующий документ с использованием update operator, метод updateOne не подходит.

Операцию вы описываете это replaceOne операции и может работать следующим образом:

sessionCollection.replaceOne(
    "_id" -> new BsonString(sessionKey), 
    sessionDocument, 
    (new UpdateOptions()).upsert(true) 
) 
+0

спасибо за помощь. Я думаю, что то, что вы предлагаете, это не то, что мне нужно. Мне нужна операция, которая вставляет новый сеанс, если он не существует с этим идентификатором, или обновляет существующий сеанс, если он существует (т. Е. «Повышение»). 'replaceOne' только последний. Когда я использую фрагмент кода, чтобы попытаться вставить новый сеанс в базу данных, он, естественно, возвращает «AcknowledgedUpdateResult» {matchedCount = 0, modifiedCount = null, upsertedId = null} 'и не влияет на базу данных. – rmin

+1

Убедитесь, что вы настроили обновление в updateOptions, я прояснил этот пример. Поскольку вы не обновляетесь с помощью оператора обновления, а скорее выполняете замену upsert, вам нужен метод replaceOne. – Ross

+2

Спасибо Росс! Он работает сейчас. Если ваш ответ должен быть scala-кодом, вы можете поместить скобки вокруг 'new UpdateOptions' - т.е. измените его на '(новые UpdateOptions) .upsert (true)'. В противном случае он не компилируется. – rmin

Смежные вопросы