Extract ObjectId from mongo in java - java

I'm working on a project and my task is to extract ObjectId from MongoDb i.e. the id of each Document and use that in a JSONObject.

One way to chieve that in Java is by using Aggregation Pipeline.
For example:
List<Bson> aggregation = new ArrayList<>(Arrays.asList(
match(new Document(FIELD, VALUE)), //your match criteria
project(new Document(FIELD1,0).append(FIELD2,0)...))); // hiding fields
// _id field is by default included - so you have to exclude eveything else

Related

Group by multiple fields using mongodb aggregate builders in java application

I am fetching data from mongodb and doing some operations using aggregates builders in my java application.
I was able to group by single field using the below piece of code.
Bson group = group("$city", sum("totalPop", "$pop"));
Bson project = project(fields(excludeId(), include("totalPop"), computed("city", "$_id")));
List<Document> results = zips.aggregate(Arrays.asList(group, project)).into(new ArrayList<>());
Now I need to group by using multiple fields...say city and location.
Can someone help on this?

Get the object id after inserting the mongodb document in java

I am using mongodb 3.4 and I want to get the last inserted document id. I have searched all and I found out below code can be used if I used a BasicDBObject.
BasicDBObject docs = new BasicDBObject(doc);
collection.insertOne(docs);
ID = (ObjectId)doc.get( "_id" );
But the problem is am using Document type not BasicDBObject so I tried to get it as like this, doc.getObjectId();. But it asks a parameter which I actually I want, So does anyone know how to get it?
EDIT
This is the I am inserting it to mongo db.
Document doc = new Document("jarFileName", jarDataObj.getJarFileName())
.append("directory", jarDataObj.getPathData())
.append("version", jarDataObj.getVersion())
.append("artifactID", jarDataObj.getArtifactId())
.append("groupID", jarDataObj.getGroupId());
If I use doc.toJson() it shows me whole document. is there a way to extract only _id?
This gives me only the value i want it like the objectkey, So I can use it as reference key.
collection.insertOne(doc);
jarID = doc.get( "_id" );
System.out.println(jarID); //59a4db1a6812d7430c3ef2a5
Based on ObjectId Javadoc, you can simply instantiate an ObjectId from a 24 byte Hex string, which is what 59a4db1a6812d7430c3ef2a5 is if you use UTF-8 encoding. Why don't you just do new ObjectId("59a4db1a6812d7430c3ef2a5"), or new ObjectId("59a4db1a6812d7430c3ef2a5".getBytes(StandardCharsets.UTF_8))? Although, I'd say that exposing ObjectId outside the layer that integrates with Mongo is a design flaw.

Java Mongo: How to get the max of each docuemnt

I have a collection with complex document, each with user Id. each userId has timestamp, so I'd like to return document for all users in organization, with the latest timestamp per each user.
This is what I tried, it sort of worked, except only the timestamp & userId fields were mapped in the result - all other data wasn't transferred:
Criteria criteria = Criteria.where("organization").is("someOrg");
Aggregation agg = newAggregation(
match(criteria),
group("userId").last("timestamp").as("timestamp")
);
AggregationResults<UserPerformanceAlert> groupResults = mongoTemplate.aggregate(agg, collectionName, UserPerformanceAlert.class);
I tried project but it kept giving me exceptions saying "java.lang.IllegalArgumentException: ExposedFields must not be null!"
Note: the full document has complex inner objects that I need to retrieve. normal find() method works just find to serialize the data to my class model.
Thanks!
Well, I just found the issue, I had to specify all the fields at the group() part:
group("userId", "type", "header", "body", "scopes", "accountId").last("timestamp").as("timestamp")

How to apply the search in list type field in dynamodb?

We are using $all in mongodb repository like below:
#Query(value = "{ 'subscriptions' : {$all : ?0 }}")
public List<ContentItem> findBySubscription(String[] subscriptionCode);
it works good for mongo but we need its alternative in dynamodb
The below solution uses AWS SDK DynamoDB. Currently, I think there is only community version of Spring data available for DynamoDB. So, I have provided the solution using AWS SDK.
QuerySpec Class
The CONTAINS comparison operator can be used to search for the values in LIST data type.
CONTAINS is supported for lists: When evaluating "a CONTAINS b", "a"
can be a list; however, "b" cannot be a set, a map, or a list.
Example:-
QuerySpec querySpec = new QuerySpec();
querySpec.withKeyConditionExpression("yearkey = :yearval and title = :title")
.withFilterExpression("contains (subscriptions, :subscriptions)")
.withValueMap(
new ValueMap().withNumber(":yearval", yearKey)
.withString(":title", title)
.withString(":subscriptions", subscriptions));
Edit:-
Currently, the second parameter can't be list because the API can't process it as per the specification. The workaround would be to use AND condition with multiple CONTAINS. Example below:-
.withFilterExpression("contains (subscriptions, :subscriptions1) AND contains (subscriptions, :subscriptions2)")

How to upsert document in MongoDB Java driver 3

what is the idiomatic way to upsert a document using version 3 of the mongodb java driver (specifically v3.0.1)?
We have a collection for sessions and when a new session gets created or modified, we want to upsert it in one operation - rather than having to query if a document exists yet and then either inserting or replacing.
Our old upsertion code used the scala driver casbah 2.7.3. It looked like:
import com.mongodb.casbah.MongoCollection
import com.mongdb.DBObject
val sessionCollection: MongoCollection = ...
val sessionKey: String = ...
val sessionDocument: DBObject = ... // Either create a new one, or find and modify an existing one
sessionCollection.update(
"_id" -> sessionKey,
sessionDocument
upsert = true
)
In our current project we're just using the plain java 3.0.1 driver and we're using BsonDocument instead of DBObject to make it more typsafe. I tried to replace the above with something like:
import com.mongodb.client.MongoCollection
val sessionCollection: MongoCollection = ...
val sessionKey: String = ...
val sessionDocument: BsonDocument = // Either create a new one, or find and modify an existing one
val updateOptions = new UpdateOptions
updateOptions.upsert(true)
sessionCollection.updateOne(
"_id" -> new BsonString(sessionKey),
sessionDocument,
updateOptions
)
This throws the error "java.lang.IllegalArgumentException: Invalid BSON field name ...". The error is covered in this question but the op in that question wasn't trying to upsert in one operation - they were using context to decide whether to replace/update/insert etc...
I'm happy with code samples in scala or java.
Thanks!
In the Mongo Java Driver 3.0 series we added a new Crud API which is more explicit and therefore beginner friendly. This initiative has been rolled out over a number of MongoDB Drivers but it does contain some changes compared to the older API.
As you are not updating an existing document using an update operator, the updateOne method is not appropriate.
The operation you describe is a replaceOne operation and can be run like so:
sessionCollection.replaceOne(
"_id" -> new BsonString(sessionKey),
sessionDocument,
(new UpdateOptions()).upsert(true)
)

Categories