我正在尝试为MongoDb集合编写一个基本的加载程序,它将从文件中读取准备好的文档并将它们插入到集合中。我使用的类目前编写如下:
package com.example;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.FileUtils;
import org.bson.Document;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.mongodb.BasicDBObject;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.IndexOptions;
public class Example {
public static void main(String[] args){
MongoCollection<Document> collection;
ObjectMapper objectMapper;
Document[] docArray;
List<Document> docList;
//Get the collection from the command line input and drop
collection = MongoClients.create("mongodb://example:password@localhost:27017/?authSource=admin").getCollection("Example");
String docListStr;
try {
String resourceFilePath = "C:\\sampledata\\example.json";
File sourceFile = new File(resourceFilePath);
if (!sourceFile.exists()) {
throw new IllegalArgumentException(String.format("The source file '%s' does not exist.", new Object[] { resourceFilePath }));
}
docListStr = FileUtils.readFileToString(sourceFile, StandardCharsets.UTF_8);
objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
docArray = objectMapper.readValue(docListStr, Document[].class);
docList = new ArrayList<>();
for (int i=0; i<docArray.length; i++) {
docList.add(docArray[i]);
}
collection.insertMany(docList);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
如果我不指定对象ID(会按预期生成一个),这可以正常工作,但我希望能够清理这个集合,并重新插入具有与之前相同ID的文档。在JSON文件中,我将对象ID与其他数据字段一起指定,如下所示:
[{
"_id": {
"$oid": "63df25a1343a3278747d6398"
},
"example": "test1",
"_class": "com.example.Example"
},
{
"_id": {
"$oid": "63df25a1343a3278747d6398"
},
"example": "test2",
"_class": "com.example.Example"
}]
然而,当我运行这个程序时,我遇到了下面的错误:
java.lang.IllegalArgumentException: Invalid BSON field name $oid
at org.bson.AbstractBsonWriter.writeName(AbstractBsonWriter.java:532)
at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.java:198)
at org.bson.codecs.DocumentCodec.writeValue(DocumentCodec.java:182)
at org.bson.codecs.DocumentCodec.beforeFields(DocumentCodec.java:167)
at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.java:192)
at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:141)
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.operation.BulkWriteBatch$WriteRequestEncoder.encode(BulkWriteBatch.java:387)
at com.mongodb.operation.BulkWriteBatch$WriteRequestEncoder.encode(BulkWriteBatch.java:377)
at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63)
at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29)
at com.mongodb.internal.connection.BsonWriterHelper.writeDocument(BsonWriterHelper.java:75)
at com.mongodb.internal.connection.BsonWriterHelper.writePayload(BsonWriterHelper.java:59)
at com.mongodb.internal.connection.CommandMessage.encodeMessageBodyWithMetadata(CommandMessage.java:143)
at com.mongodb.internal.connection.RequestMessage.encode(RequestMessage.java:138)
at com.mongodb.internal.connection.CommandMessage.encode(CommandMessage.java:57)
at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:244)
at com.mongodb.internal.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:99)
at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:444)
at com.mongodb.internal.connection.CommandProtocolImpl.execute(CommandProtocolImpl.java:72)
at com.mongodb.internal.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:200)
at com.mongodb.internal.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:269)
at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:131)
at com.mongodb.operation.MixedBulkWriteOperation.executeCommand(MixedBulkWriteOperation.java:419)
at com.mongodb.operation.MixedBulkWriteOperation.executeBulkWriteBatch(MixedBulkWriteOperation.java:257)
at com.mongodb.operation.MixedBulkWriteOperation.access$700(MixedBulkWriteOperation.java:68)
at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:201)
at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:192)
at com.mongodb.operation.OperationHelper.withReleasableConnection(OperationHelper.java:424)
at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:192)
at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:67)
at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:193)
at com.mongodb.client.internal.MongoCollectionImpl.executeInsertMany(MongoCollectionImpl.java:520)
at com.mongodb.client.internal.MongoCollectionImpl.insertMany(MongoCollectionImpl.java:504)
at com.mongodb.client.internal.MongoCollectionImpl.insertMany(MongoCollectionImpl.java:499)
如何解决此问题以允许在文件中指定对象ID?
更新:
我目前有一个变通方法,就是检查列表中每个Document的键集,如果它匹配“_id”,则获取相应的值,将其解析为字符串以获取$oid属性并转换为ObjectId。然后删除现有的“_id”键-值对,并将其添加回ObjectId类型:
for (Document docListEntry: docList) {
if (docListEntry.get("_id") != null) {
ObjectId objectId = new ObjectId(docListEntry.remove("_id").toString().split("}")[0].split("=")[1]);
docListEntry.put("_id",objectId);
}
}
不是很干净,但暂时解决了我的问题
1条答案
按热度按时间j2datikz1#
你可以升级你的mongo驱动版本。我用下面的版本工作正常。
你也可以使用下面的代码来获取文档列表更容易.
EDIT:添加
$
后,可以使用Document.parse
代替objectMapper.readValue
,如下所示。