2016-11-09 30 views
0

在我的MongoDB文档的JSON看起来像这样过滤YearMonth从蒙戈文件

{ "_id" : ObjectId("582258c899f8b36081979d1b"), "customer" : "company-name", "start" : { "year" : 2016, "month" : 11 }, "end" : { "year" : 2016, "month" : 11 } 

现在我想用一个YearMonth可变我在我的Java代码,所以我比较筛选出在球场上的“开始”为此

public ContractDTO findContractFor(String customer, YearMonth period) { 
    BasicDBObject query = new BasicDBObject(); 
    query.put("start", new BasicDBObject("$eq", period)); 
    MongoCollection<Document> collection = database.getCollection("contract"); 
    FindIterable<Document> documents = collection.find(query); 
    Document first = documents.first(); 

执行的最后一行上面时,我得到以下异常

org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class java.time.YearMonth. 
    at org.bson.codecs.configuration.CodecCache.getOrThrow(CodecCache.java:46) 
    at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:63) 
    at org.bson.codecs.configuration.ChildCodecRegistry.get(ChildCodecRegistry.java:51) 
    at com.mongodb.DBObjectCodec.writeValue(DBObjectCodec.java:210) 
    at com.mongodb.DBObjectCodec.encodeMap(DBObjectCodec.java:220) 
    at com.mongodb.DBObjectCodec.writeValue(DBObjectCodec.java:196) 
    at com.mongodb.DBObjectCodec.encode(DBObjectCodec.java:128) 
    at com.mongodb.DBObjectCodec.encode(DBObjectCodec.java:61) 
    at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63) 
    at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29) 
    at org.bson.codecs.EncoderContext.encodeWithChildContext(EncoderContext.java:91) 
    at org.bson.codecs.BsonDocumentCodec.writeValue(BsonDocumentCodec.java:133) 
    at org.bson.codecs.BsonDocumentCodec.encode(BsonDocumentCodec.java:112) 
    at org.bson.codecs.BsonDocumentCodec.encode(BsonDocumentCodec.java:40) 
    at com.mongodb.connection.RequestMessage.addDocument(RequestMessage.java:253) 
    at com.mongodb.connection.RequestMessage.addDocument(RequestMessage.java:205) 
    at com.mongodb.connection.CommandMessage.encodeMessageBodyWithMetadata(CommandMessage.java:75) 
    at com.mongodb.connection.RequestMessage.encodeWithMetadata(RequestMessage.java:160) 
    at com.mongodb.connection.CommandProtocol.sendMessage(CommandProtocol.java:192) 
    at com.mongodb.connection.CommandProtocol.execute(CommandProtocol.java:111) 
    at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:159) 
    at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:286) 
    at com.mongodb.connection.DefaultServerConnection.command(DefaultServerConnection.java:173) 
    at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:215) 
    at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:206) 
    at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:112) 
    at com.mongodb.operation.FindOperation$1.call(FindOperation.java:487) 
    at com.mongodb.operation.FindOperation$1.call(FindOperation.java:482) 
    at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:239) 
    at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:212) 
    at com.mongodb.operation.FindOperation.execute(FindOperation.java:482) 
    at com.mongodb.operation.FindOperation.execute(FindOperation.java:79) 
    at com.mongodb.Mongo.execute(Mongo.java:772) 
    at com.mongodb.Mongo$2.execute(Mongo.java:759) 
    at com.mongodb.FindIterableImpl$FindOperationIterable.first(FindIterableImpl.java:207) 
    at com.mongodb.FindIterableImpl.first(FindIterableImpl.java:148) 

我不能通过看文档如何让这个工作。非常感谢您在某个方向获得提示。

回答

1

您将需要为年份创建自定义编解码器,因为这不是标准的Bson类型。这涉及两个步骤。根据您的需求进行调整。

创建编解码器

public class YearMonthCodec implements Codec<YearMonth> { 

    public void encode(BsonWriter writer, YearMonth value, EncoderContext encoderContext) { 

     writer.writeStartDocument(); 

     writer.writeName("year"); 
     writer.writeInt32(value.getYear()); 
     writer.writeName("month"); 
     writer.writeInt32(value.getMonth().getValue()); 

     writer.writeEndDocument(); 

    } 

    public Class<YearMonth> getEncoderClass() { 
     return YearMonth.class; 
    } 

    public YearMonth decode(BsonReader reader, DecoderContext decoderContext) { 

     reader.readStartDocument(); 

     int year = reader.readInt32("year"); 
     int month = reader.readInt32("month"); 

     reader.readEndDocument(); 

     return YearMonth.of(year, month); 

    } 

} 

与蒙戈客户

CodecRegistry codecRegistry = CodecRegistries.fromRegistries(CodecRegistries.fromCodecs(new YearMonthCodec()), 
     MongoClient.getDefaultCodecRegistry()); 
MongoClientOptions options = MongoClientOptions.builder().codecRegistry(codecRegistry).build(); 
MongoClient mongoClient = new MongoClient(new ServerAddress(), options); 
+0

由于注册的编解码器!我看到其他人得到了类似的答案,但我认为我的情况有所不同,因为我能够在Bson和Java之间序列化/反序列化YearMonth字段,而没有做任何特殊的事情。但也许这是比较/过滤的另一件事。 – svaret

+0

序列化/反序列化如何在没有编解码器实现的情况下工作? – svaret

+1

你可以添加一个没有编解码器的例子吗? – Veeram