从 Mongo 文档中过滤 YearMonth [英] Filtering YearMonth from Mongo document
问题描述
在我的 MongoDB 文档中,json 看起来像这样
In my MongoDB document the json looks like this
{ "_id" : ObjectId("582258c899f8b36081979d1b"), "customer" : "company-name", "start" : { "year" : 2016, "month" : 11 }, "end" : { "year" : 2016, "month" : 11 }
现在我想通过与 Java 代码中的 YearMonth 变量进行比较来过滤掉开始"字段,所以我这样做
Now I want to filter out on the field "start" by comparing with a YearMonth variable I have in my java code so I do this
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();
当执行上面的最后一行时,我得到以下异常
When executing the last line above I get the following exception
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)
我无法通过查看文档来弄清楚如何使其工作.非常感谢您在某个方向上获得提示.
I can't figure out by looking at the docs how to get this to work. Would be very appreciated to get a hint in some direction.
推荐答案
您需要为 Year Month 创建自定义编解码器,因为这不是标准的 Bson 类型.这包括两个步骤.根据您的需要进行调整.
You will need to create custom codec for Year Month as this is not a standard Bson type. This involves two steps. Adjust based on your needs.
创建编解码器
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 客户端注册编解码器
Register the codec with the Mongo client
CodecRegistry codecRegistry = CodecRegistries.fromRegistries(CodecRegistries.fromCodecs(new YearMonthCodec()),
MongoClient.getDefaultCodecRegistry());
MongoClientOptions options = MongoClientOptions.builder().codecRegistry(codecRegistry).build();
MongoClient mongoClient = new MongoClient(new ServerAddress(), options);
这篇关于从 Mongo 文档中过滤 YearMonth的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!