Hi mongodb community,
I would be very grateful for help with the following issue.
It is about a document containing yearly activities for a user:
{
"_id": {
"$oid": "6437db5e791549e390d8a0f0"
},
"idUser": "testUser1",
"numYear": 2023,
"activities": {
"63ff26237d68b622e28852b3": {
"_id": { "$oid": "63ff26237d68b622e28852b3" },
"tstActivity": { "$date": "2023-03-01T11:17:06.000Z" },
"txtNameActivity": "testActivity1"
},
"63ff2fff7d68b622e2886288": {
"_id": { "$oid": "63ff2fff7d68b622e2886288" },
"tstActivity": { "$date": "2023-03-01T11:59:11.000Z" },
"txtNameActivity": "testActivity2"
}
}
}
We have some edge-cases, where such a document grows too big, causing:
WriteError{code=17419, message='Resulting document after update is larger than 16777216', details={}}
All mongodb access happens through java services (using only the native mongodb java driver).
So the basic idea to cope with the issue is:
- On upsert of a new activity catch the exception for this specific error: (
MongoWriteException.getError().getCode() == 17419
) - If that happens, delete the activity with the minimum key (hex string representation of _id) and try again until success
And the question would be about how point (2) can be solved in an efficient way.
This is the approach I have so far:
Bson match = Aggregates.match(Updates.combine(
Filters.eq("numYear", 2023),
Filters.eq("idUser", testUser1)));
Bson addFields = Aggregates.addFields(new Field("activityArray",
new Document("$objectToArray", "$activities")));
Bson project = Aggregates.project(Projections.fields(
Projections.excludeId(),
Projections.computed("minActivityKey",
new Document("$min", "$activityArray.k"))));
MongoCollection<Activities> mongoCollection = mongoDatabase
.getCollection("activities", Activities.class);
AggregateIterable<Activities> aggregate = mongoCollection.aggregate(
Arrays.asList(match, addFields, project));
Bson unset = Updates.unset("activities." +
aggregate.first().getMinActivityKey());
mongoCollection.updateOne(match, unset);
The problem about this is, that the “Activities” class represents the document schema and consequently does not contain the aggregated field “minActivityKey”.
So my question would be if there is a way to access the result of aggregation pipelines without mapping it to the class the MongoCollection is associated with?
In case anyone know of better options or best practices to achieve this possibly not so uncommon issue, I would also be very glad for input.
Thank you in advance and br,
Jan