この例外:
_Exception in thread "Thread-1" Java.lang.IllegalArgumentException: Invalid BSON field name id
at org.bson.AbstractBsonWriter.writeName(AbstractBsonWriter.Java:516)
at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.Java:188)
at org.bson.codecs.DocumentCodec.encode(DocumentCodec.Java:131)
at org.bson.codecs.DocumentCodec.encode(DocumentCodec.Java:45)
at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.Java:63)
at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.Java:29)
at com.mongodb.connection.UpdateCommandMessage.writeTheWrites(UpdateCommandMessage.Java:85)
at com.mongodb.connection.UpdateCommandMessage.writeTheWrites(UpdateCommandMessage.Java:43)
at com.mongodb.connection.BaseWriteCommandMessage.encodeMessageBodyWithMetadata(BaseWriteCommandMessage.Java:129)
at com.mongodb.connection.RequestMessage.encodeWithMetadata(RequestMessage.Java:160)
at com.mongodb.connection.WriteCommandProtocol.sendMessage(WriteCommandProtocol.Java:220)
at com.mongodb.connection.WriteCommandProtocol.execute(WriteCommandProtocol.Java:101)
at com.mongodb.connection.UpdateCommandProtocol.execute(UpdateCommandProtocol.Java:64)
at com.mongodb.connection.UpdateCommandProtocol.execute(UpdateCommandProtocol.Java:37)
at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.Java:168)
at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.Java:289)
at com.mongodb.connection.DefaultServerConnection.updateCommand(DefaultServerConnection.Java:143)
at com.mongodb.operation.MixedBulkWriteOperation$Run$3.executeWriteCommandProtocol(MixedBulkWriteOperation.Java:490)
at com.mongodb.operation.MixedBulkWriteOperation$Run$RunExecutor.execute(MixedBulkWriteOperation.Java:656)
at com.mongodb.operation.MixedBulkWriteOperation$Run.execute(MixedBulkWriteOperation.Java:409)
at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.Java:177)
at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.Java:168)
at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.Java:422)
at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.Java:413)
at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.Java:168)
at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.Java:74)
at com.mongodb.Mongo.execute(Mongo.Java:845)
at com.mongodb.Mongo$2.execute(Mongo.Java:828)
at com.mongodb.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.Java:550)
at com.mongodb.MongoCollectionImpl.update(MongoCollectionImpl.Java:542)
at com.mongodb.MongoCollectionImpl.updateOne(MongoCollectionImpl.Java:381)
at org.hpms.gis.MongoDbTest.insert(MongoDbTest.Java:63)
at Java.lang.Thread.run(Thread.Java:748)
_
次のコードによってスローされます。
_ final UUID id = UUID.randomUUID();
final double frequency = 8_000.0 + ( 10_000.0 * Math.random() );
final double startSec = 100*i;
final double startNano = 10*i;
final double endSec = startSec + ( 100*i );
final double endNano = startNano + ( 10*i );
final double latitude = ( 180.0*Math.random() ) - 90.0;
final double longitude = ( 360.0*Math.random() ) - 180.0;
final Document trackID = new Document(
"id", new Document(
"msb", id.getMostSignificantBits ()) .append(
"lsb", id.getLeastSignificantBits()));
final Document track = new Document(
"id", new Document(
"msb", id.getMostSignificantBits ()) .append(
"lsb", id.getLeastSignificantBits())).append(
"frequency", frequency ) .append(
"start", new Document(
"seconds", startSec ) .append(
"nanoSec", startNano )).append(
"end", new Document(
"seconds", endSec ) .append(
"nanoSec", endNano )).append(
"position", new Document(
"latitude" , latitude ) .append(
"longitude", longitude )).append(
"padding", new byte[1000-8-8-8-4-4-4-4-8-8] );
//_collection.insertOne( track );
_collection.updateOne(
trackID,
track,
new UpdateOptions().upsert( true ));
_
コメントされたコード_collection.insertOne( track );
は正常に実行されます。
「upsert」がそうでないときに挿入がうまくいくのはなぜですか
updateOne
は、更新演算子を使用してドキュメントフィールドを更新します。置換ドキュメントを受け取るreplaceOne
が必要です。
_collection.replaceOne(
trackID,
track,
new UpdateOptions().upsert( true ));
詳細はこちら
更新演算子: https://docs.mongodb.com/manual/reference/operator/update-field/
アップデート1: https://docs.mongodb.com/manual/reference/method/db.collection.updateOne/
置換1つ: https://docs.mongodb.com/manual/reference/method/db.collection.replaceOne/
MongoDBのドキュメントに示されているように、別のオプションはsetOnInsert
です。
https://docs.mongodb.com/manual/reference/operator/update/setOnInsert/
この操作は、upsert
がtrue
の場合にのみ機能します。
あなたのケースでは、変更されないフィールドをドキュメントに、更新されるフィールドを別のドキュメントに、そして3番目のドキュメントにそれぞれ$setOnInsert
と$set
をキーとして追加する必要があります。
$setOnInsert
の大きな利点は、挿入時に$setOnInsert
and$set
partを実行するが、更新すると、$set
のみが実行されます。
たとえば、挿入/更新するドキュメントには、name
、age
、gender
、createAt
、updateAt
の5つのフィールドがあります。
createAt
およびupdateAt
に現在の日時を入力します。name
とupdateAt
を現在の日時で更新したいです。私がやることは:
query = Filters.eq("name", nameToSearch);
Document upsert = new Document();
Date now = new Date();
//only fields not mentioned in "$set" is needed here
Document toInsert = new Document()
.append("age", newAge)
.append("gender", genderString)
.append("createAt", now);
//the fields to update here, whether on insert or on update.
Document toUpdate = new Document().append("name", nameToSearch)
.append("updateAt", now);
//will:
// - insert 5 fields if query returns no match
// - updates 2 fields if query returns match
upsert.append("$setOnInsert", toInsert)
.append("$set", toUpdate);
UpdateResult result = collection.updateOne(query, toUpdate,
new UpdateOptions().upsert(true));