How to retrieve and remove embedded document spring data mongodb - java

There I am stuck, how to remove embedded document in mongodb. I am using spring data mongodb criteria, I am doing it like the following:
// database
"_id" : ObjectId("55683d51e4b0b6050c5b0db7"),
"_class" : "com.samepinch.domain.metadata.Metadata",
"preferenceType" : "SHOPPING",
"subtypes" : [
{
"_id" : ObjectId("55683d51e4b0b6050c5b0db6"),
"leftValue" : "VEG",
"rightValue" : "NON_VEG",
"preferencePoint" : 0
}
],
"createdDate" : ISODate("2015-05-29T10:20:01.610Z"),
"updatedDate" : ISODate("2015-05-29T10:20:01.610Z")
// query
mongoTemplate.updateMulti(new Query(),
new Update().pull("subtypes", Query.query(Criteria.where("subtypes._id").is(new objectId("55683d51e4b0b6050c5b0db6"))),Metadata.class);
What i am doing wrong?
Thanks in advance!

subtypes is in nested objects so you should first pass this in $elemMatch is matched first matching array elements of given conditions. Update query as :
db.updateMulti.update({"subtypes":{"$elemMatch":{"_id":ObjectId("55683d51e4b0b6050c5b0db6")}}},
{"$pull":{"subtypes":{"_id":ObjectId("55683d51e4b0b6050c5b0db6")}}})
this query pull exact matching array elements from subtypes array .
And with the help of this spring elemMatch ( not that much expertise in spring mongo ) I converted this query in spring format as below :
mongoTemplate.updateMulti(new Query(
where("subtypes").elemMatch(where("_id").is(ew objectId("55683d51e4b0b6050c5b0db6"))).pull(
pull("subtypes", Query.query(Criteria.where("_id").is(new objectId("55683d51e4b0b6050c5b0db6"))),Metadata.class
));
this above spring query not tested I hope you will convert mongo update query in spring mongo query format.

Related

How do I convert String to an Object in MongoDB?

In my Mongo database, I have a "Books" collection with a "category" field. In the past, "category" was an enum mapped as String in Mongo but now I need "category" to be an object within my "Books" collection. What can I do? Is there a query that can be executed to convert all documents at once?
Example, today category is like that:
"category" : "Sci-Fi and Fantasy"
But I need to convert to this:
"category" : {
"_id" : ObjectId("3f07bc56po324021df23a8f1"),
"code" : NumberLong(1),
"name" : "Sci-Fi and Fantasy"
}
MongoDB is no SQL you can have both kind of records present in your mongo collection, although while reading the records you might have to frame some logic for creating identical entities. This might cause issues if you search based on that particular property.
You can create a new property with different name keeping the category as well and then add the new property to all the records.

All operator in mongo using Spring

How can I use #Query annotation in spring to query an array in mongo Document.
eg:
user_id : 1
tags : ['scientist','biologist','mathematician','chemist'];
user_id : 1
tags : ['scientist','physicist','carpenter','chemist'];
I am query making api and the URL is something like this:
localhost:8080/tags=scientist,biologist // should return 1st document
or
localhost:8080/tags=physicist,carpenter // should return 2nd document
There can be any number of tags in the url and the tag array must contain all the tags present in the url.
How can I acheive this?
You could try the query annotation which uses the $or operator as
#Query("{'$or' : [{ 'tags': ?0, 'tags': ?1 }]}")
public List<Tags> findByTagsFirstorSecond(string firstTag, string secondTag);

ObjectId in mongoDB 2.6 not working

I'm using spring data mongodb in my application. It uses mongodb 2.6. I want to query documents of a collection by the id which mongo assigns during insertion. I'm doing something like this:
Query query = new Query();
String id = "542385a91f00bf7dbeae1fc7";
query.addCriteria(Criteria.where("_id").new Object(id));
template.find(query, entity.class);
This query translates to:
{ "_id" : { "$oid" : "542385a91f00bf7dbeae1fc7"}}
When I execute the same on mongo shell, it gives an error:
error: {
"$err" : "Can't canonicalize query: BadValue unknown operator: $oid",
"code" : 17287
}
How do I query by id using spring data mongodb?
It should read
new ObjectId(id)
instead of new Object(id). Please see the API docs for details.

java mongodb search on a given date

We have a user_audit entity(table) in mongodb which stores all the login/logout information.
For example,
"_id" : ObjectId("5228cf0156961de6693b74c0"),
"active" : true,
"fname" : "Tom",
"lastlogin" : ISODate("2013-09-05T18:35:45.608Z"),
"lastloginip" : "0:0:0:0:0:0:0:1",
"lname" : "Bailey",
"lastlogout" : ISODate("2013-09-05T18:36:45.568Z"),
There are thousands of records in this table in production.
Now, the admin wants to look for all the logins on a particular date. i am not able to look for exact match of date because of the "time" information attached to ISODate in the "lastlogin" field. In Java, new Date() had been used to insert this field value.
The issue is the time information keeps changing for logins on a particular day.
Tried,
query.put("lastlogin", new BasicDBObject("$lte", givenDate).append("$gte", givenDate));
Obviously it does not return results because the time part of the date does not match.
The query passed from Java to mongo is:
query={ "lastlogin" : { "$lte" : { "$date" : "2013-09-05T04:00:00.000Z"} , "$gte" : {
"$date" : "2013-09-05T04:00:00.000Z"}}}
[Note: It defaults to 04:00:00.000Z always if we format with MM_dd_yyyy in java, not sure why..]
The issue is we have a lot of records in production database. For fresh records, i can blank out the time portion before inserting from Java. But for existing records, not sure how to handle it. How can i get the records on a given date?
According to mongodb cookbook, you are in the right direction. You may just query for something like
query.put("lastlogin", new BasicDBObject("$lt", givenDatePlusOneDay).append("$gte", givenDateAt00h00min));
which is an interval and not the same date.

Unexpected MongoDB "OR" query behaviour

I'm testing out spring-data and it's mongodb support.
I have a question about the query creation when using or-queries. Consider the following:
Query query = new Query().or(new Query(where("receiverId").is(userId)), new Query(where("requesterId").is(userId)));
query.and(where("status").is(status));
This will result in the following mongodb query:
"$or" : [ { "receiverId" : { "$oid" : "4d78696025d0d46b42d9c579"}} , { "requesterId" : { "$oid" : "4d78696025d0d46b42d9c579"}}] , "status" : "REQUESTED"}
This returns zero results while one is expected. Running this query in mongodb command results in following error:
error: { "$err" : "invalid operator: $oid", "code" : 10068 }
Modifying the query and running it in mongodb command works fine:
{ "$or" : [ { "receiverId" : ObjectId("4d78696025d0d46b42d9c579")} , { "requesterId" : ObjectId("4d78696025d0d46b42d9c579")}] , "status" : "REQUESTED"}
Notice the use of ObjectId("...") instead of $oid.
Am I going about something the wrong way? Maybe setting up the query wrong?
Are you inspecting that query variable at runtime or is that what you are seeing in MongoDB's logs?
Int he C# driver, if you inspect the query variable, you see $oid as well, but that is not the actual query that is sent to the server. At some point, it changes that to a valid MongoDB query.
If you are running on linux, you may want to start up mongosniff which will show you realtime queries, updates and inserts as they happen. If you are on Windows, you should start up mongod.exe with -vvvv flag which will enable it to log every query, update, insert, or command to the log file.
Then you can actually see the exact query that is being submitted.

Categories