-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Simplify usage of user provided aggregation operations. #4059
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Introduce Aggregation.stage which allows to use a plain JSON String or any valid Bson representation to be used within an aggregation pipeline stage, without having to implement AggregationOperation directly. The change allows to make use of driver native builder API for aggregates.
|
||
@Override | ||
default CodecRegistry getCodecRegistry() { | ||
return MongoClientSettings.getDefaultCodecRegistry(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In practice, when (if ever) will this default implementation be used? The underlying driver never uses this method, because it doesn't take into account important user configuration (most notably, the UUID representation).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it’s public API that users may have implemented, defaulting here eases the pain when upgrading to the new version. Internal implementations pick up the driver registry.
Are custom codecs heavily used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main thing is that even the default registry is changed in the MongoClient constructor in order to apply the uuidRepresentation to the registry. The default registry will throw when trying to encode a UUID value, because the default UuidRepresentation is UNSPECIFIED
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a note: MongoClientSettings.getDefaultCodecRegistry()
is also used explicitly in the default implementation of the MongoConverter.getCodecRegistry
method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
true, same reason for those upgrading. As long as the user does not provide a custom implementation of the converter the codec registry (with all the user settings regarding UUID codec,...) will be used.
public static Map<String, Object> asMap(@Nullable Bson bson, CodecRegistry codecRegistry) { | ||
|
||
if (bson == null) { | ||
return Collections.emptyMap(); | ||
} | ||
if (bson instanceof BasicDBObject) { | ||
return ((BasicDBObject) bson); | ||
|
||
if (bson instanceof Document document) { | ||
return document; | ||
} | ||
if (bson instanceof DBObject) { | ||
return ((DBObject) bson).toMap(); | ||
if (bson instanceof BasicDBObject dbo) { | ||
return dbo; | ||
} | ||
if (bson instanceof DBObject dbo) { | ||
return dbo.toMap(); | ||
} | ||
|
||
return (Map) bson.toBsonDocument(Document.class, MongoClientSettings.getDefaultCodecRegistry()); | ||
return new Document((Map) bson.toBsonDocument(Document.class, codecRegistry)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Should
org.bson.BsonDocument
be also included as a special case? It is aMap
withString
keys, just likeDocument
andBasicDBObject
. - Should
BasicDBObject
be replaced with its supertypeorg.bson.BasicBSONObject
?BasicBSONObject
is aMap
withString
keys. bson.toBsonDocument(Document.class, codecRegistry)
is aMap<String, BsonValue>
. Couldn't it be returned without shallowly copying its content in a newDocument
? The methodBsonUtils.asDocument
will still do this copying, but at least it will be done exactly where it is needed, instead of being done when there may be no need, which may be the case whenasMap
is called not fromasDocument
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the additional Document
wrapping can be removed, yes.
The BasicDBObject
is still in there from 2.x generation and likely to be completely removed for 4.x.
if (value instanceof Document document) { | ||
return document; | ||
} | ||
|
||
if (value instanceof Bson bson) { | ||
return BsonUtils.asDocument(bson, context.getCodecRegistry()); | ||
} | ||
|
||
if (value instanceof Map map) { | ||
return new Document(map); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BsonUtil.asMap
does not allow itself a liberty of just checking instanceof Map
. I think that's because this check does not guarantee that the map keys are of the String
type. For this reason, I don't think that
if (value instanceof Map map) {
return new Document(map);
}
is a type-safe code. Am I missing something?
Given the above, and that BsonUtil.asMap
and BsonUtil.asDocument
already check for special cases when some work may be skipped, can't the three if
blocks be replaced with
if (value instanceof Bson bson) {
return BsonUtils.asDocument(bson, context.getCodecRegistry());
}
?
if (bson instanceof Document document) { | ||
return document; | ||
} | ||
|
||
Map<String, Object> map = asMap(bson); | ||
Map<String, Object> map = asMap(bson, codecRegistry); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that asMap
already does the instanceof Document
check, this check may be safely removed here.
|
||
@Override | ||
default CodecRegistry getCodecRegistry() { | ||
return MongoClientSettings.getDefaultCodecRegistry(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a note: MongoClientSettings.getDefaultCodecRegistry()
is also used explicitly in the default implementation of the MongoConverter.getCodecRegistry
method.
Introduce Aggregation.stage which allows to use a plain JSON String or any valid Bson representation to be used within an aggregation pipeline stage, without having to implement AggregationOperation directly. The change allows to make use of driver native builder API for aggregates. Original pull request: #4059. Closes #4038
That's merged and polished now. |
Introduce
Aggregation.stage
which allows to use a plain JSON String or any validBson
representation to be used within an aggregation pipeline stage, without having to implementAggregationOperation
directly.The change allows to make use of driver native builder API for aggregates.