从Mongo文档过滤YearMonth

时间:2016-11-09 22:21:06

标签: java mongodb

在我的MongoDB文档中,json看起来像这样

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

现在我想通过比较我在java代码中的YearMonth变量来过滤掉“start”字段,所以我这样做

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 个答案:

答案 0 :(得分:1)

您需要为Year Month创建自定义编解码器,因为这不是标准的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);

    }

}   

向Mongo客户端注册编解码器

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