I have to write a complex mongo query using java but am not able to do it.
The mongo query looks like this:
db.video.findOne( {
$or: [
{ key1: { $in : [764] } },
{ key2: {$in : [list2] } },
{ $and [ { key2 : 3}, {key4:67} ] }
]
})
I have to write the above query using the QueryBuilder class. In what way can I do it?
Thanks
Using QueryBuilder your query should look like this
DBObject query = QueryBuilder.start().or(
QueryBuilder.start("key1").in(764).get(),
QueryBuilder.start("key2").in(keys).get(),
QueryBuilder.start().and("key3").is(3).and("key4").is(64).get()
).get();
Consider using jongo (an API over mongo-java-driver) you can simply copy/paste queries from the shell :
collection.findOne("{$or:[{key1: {$in:[764]}},{key2:{$in:[#]}}, {$and:[{key3:3},{key4:67}]}]}", keys).as(People.class);
I had the same problem and i got a solution in another way :
ArrayList orList = new ArrayList();
ArrayList andList = new ArrayList();
orList.add(new BasicDBObject("key1", new BasicDBObject("$in", 764)));
orList.add(new BasicDBObject("key2", new BasicDBObject("$in", list2)));
andList.add(new BasicDBObject("key2", 3));
andList.add(new BasicDBObject("key4", 67));
orList.add(new BasicDBObject("$and", andList));
BasicDBObject query = new BasicDBObject("$or", orList);
Related
I have a following query for my mongodb. How to translate it to the equivalent code in spring data mongodb:
db.getCollection('account').find({
colorList: {$elemMatch: {
$eq:"577b"
}
}
})
one of the account collection is shown as below:
{
"_id" : ObjectId("133b6ca05e7c058819ab6e6c"),
"fleetList" : [
"577b",
"123b"
]
}
Instead of using $elemMatch and $eq, you can use $in for your query too. This query makes exactly that your query does:
db.account.find({ "colorList": { $in: ["577b"] } });
And for spring-data-mongodb method for this query is:
List<Account> findByColorListIn(List<String> colorIds); //In your case colorIds list has one element only.
If you want to stick with your query:
#Query("{'colorList': {\$elemMatch: {\$eq: ?0}}}")
List<Account> findByColorList(String colorId)
Just a quick question about something I've just experienced and I'm still thinking about why:
mongos> db.tickets.count({ "idReferenceList" : { "$in" : [ { "$oid" : "53f1f09f2cdcc8f339e5efa2"} , { "$oid" : "5409ae2e2cdc31c5aa0ce0a5"}]}});
0
mongos> db.tickets.count({ "idReferenceList" : { "$in" : [ ObjectId("53f1f09f2cdcc8f339e5efa2") , ObjectId("5409ae2e2cdc31c5aa0ce0a5")]}});
2
I thought that both $oid and ObjectId spelling formats where exactly the same for MongoDB. Does anyone know why with the first query return 0 results and with the second one is returning 2 (the right answer)?
Furthermore, I'm using Morphia framework which uses MongoDB Java driver to interact with MongoDB. I've realised that there exists a problem by searching with $in operator in ObjectIds arrays over fields that are not _id by executing this lines of code:
List< ObjectId > fParams = new ArrayList< ObjectId >();
fParams.add(...);
Query<Ticket> query = genericDAO.createQuery();
query.field("idReferenceList").in(fParams);
result = genericDAO.find(query).asList();
Thank you very much in advance.
Regards,
Luis Cappa
Both these formats are valid representations of an object id in MongoDB, according to the documentation,
http://docs.mongodb.org/manual/reference/mongodb-extended-json/
and they represented differently in the two modes,
Strict Mode mongo Shell Mode
----------- ----------------
{ "$oid": "<id>" } ObjectId( "<id>" )
So, to query fields which contain objectid, from the shell/console mode, you need to use ObjectId("<id>").
Which is the syntax to be followed in the mongo shell mode.
Hence the query:
db.tickets.count({ "idReferenceList" : { "$in" : [ ObjectId("53f1f09f2cdcc8f339e5efa2") , ObjectId("5409ae2e2cdc31c5aa0ce0a5")]}});
would return you row count.
Now to do it via the Java API,
You need to do it as below:
String[] ids = {"53f1f09f2cdcc8f339e5efa2","5409ae2e2cdc31c5aa0ce0a5"};
ObjectId[] objarray = new ObjectId[ids.length];
for(int i=0;i<ids.length;i++)
{
objarray[i] = new ObjectId(ids[i]);
}
BasicDBObject inQuery = new BasicDBObject("$in", objarray);
BasicDBObject query = new BasicDBObject("idReferenceList", inQuery);
DBCursor cursor = db.collection.find(query);
while(cursor.hasNext())
{
DBObject doc = cursor.next();
// process the doc.
}
I faced the same issue.
I resolved like this way.
db.collection('post').find({ 'postIds': { $elemMatch: { $in:
deletedPosts.map(_post => {ObjectId(_post._id)}) } } })
My app is dynamically generating a mongo query via a QueryBuilder. I'm trying to make it so that the passed text can be compared against several fields in my collection. I need to iterate through data in order to know what to add to the $OR ( 'text_to_compare' vs title field, 'text_to_compare vs body field), so I've been trying to store each section of the $OR clause in a BasicDBList as follows:
BasicDBObject orsDBObject = new BasicDBObject();
BasicDBList orsList = new BasicDBList();
for( String dbFieldNameInstance: listDBFieldName ){
QueryBuilder innerQB = new QueryBuilder();
innerQB.put(dbFieldNameInstance).is(obj.getValue()); //using this inner QueryBuilder to assist in creating the document
orsList.add(innerQB.get());
}
orsDBObject.putAll(orsList); //put each of the BasicDBList items into a BasicDBObject
qb.or(orsDBObject); //finally, add the entire $OR clause to my bigger querybuilder
System.out.println("qb: " + qb.get());
It seems like I might be jumping through more conversions than are necessary. It isn't working either. The output from the above ends up looking like this:
qb: { "$or" : [ { "0" : { "primary_industries_names" : "electrical"} , "1" : { "primary_industries_aliases" : "electrical"} , "2" : { "secondary_industries_names" : "electrical"} , "3" : { "secondary_industries_aliases" : "electrical"} , "4" : { "product_experience_names" : "electrical"} , "5" : { "product_experience_aliases" : "electrical"}}]}
For the most part it looks right to me, however I don't think the "0": should be appearing in there. Any advice would be greatly appreciated.
You kind of have that the wrong way around. Not re-writing your code, but you should get the idea:
// Before the loop
QueryBuilder qb = new QueryBuilder();
// And loop things like this
for ( ) {
qb.or(new BasicDBObject("this","that"));
}
// After loop
System.out.println(qb.get());
If you are trying to nest several conditions then you seem to be missing the $and operator. Consider the following:
QueryBuilder qb = new QueryBuilder();
for (int x=0; x<2;x++) {
qb.or(new BasicDBObject("this","that"));
}
QueryBuilder qb2 = new QueryBuilder();
qb2.and(qb.get());
QueryBuilder qb3 = new QueryBuilder();
for (int x=0; x<2;x++) {
qb3.or(new BasicDBObject("something", "else"));
}
qb2.and(qb3.get());
System.out.println(qb2.get());
I'm somewhat new to mongo. I want to query on a field for multiple values.
In SQL, I want something like this:
select * from table where field in ("foo","bar")
Suppose I have the following documents in mongodb
{
"_id":"foo"
}
{
"_id":"bar"
}
I simply want to mimic this query:
db.coll.find( { _id: { $in: [ "foo", "bar" ] } } );
I want to retrieve all documents whose _id is either "foo" or "bar".
And I'd like to do this using the java driver.
I tried something like
BasicDBObject query = new DBObject()
query.append("_id","foo");
query.append("_id","bar");
collection.find(query);
But that seems to return only the "bar" document.
Please help
To use the $in operator, it may be easier to use QueryBuilder to create the query like this:
QueryBuilder qb = new QueryBuilder();
qb.put("_id").in(new String[] {"foo", "bar"});
collection.find(qb.get());
or a little cleaner:
DBObject query = QueryBuilder.start("_id").in(new String[] {"foo", "bar"}).get();
collection.find(query);
I am trying to build an $in query with QueryBuilder (MongoDB Java API 2.9.1). I have no problem when the query is an array of strings but when I try with an array of ObjectIds it doesn't work (returns nothing).
I am able to run the query successfully and get a result from the console:
Query in console:
db.collection.find({removed:false,app_id: {$in : [ObjectId("4f75c533ac99d845186e19b2"), ObjectId("4f75c533ac99d845186e19b3")]}})
Query created by QueryBuilder (MongoDB Java API 2.9.1):
Object[] ids;
Java code:
DBObject query = QueryBuilder.start("app_id").in(ids).and("removed").is(false).get();
ToString on DBObject produces:
{ "app_id" : { "$in" : [ { "$oid" : "4f75c533ac99d845186e19b2"}]} , "removed" : false}
Not sure if I am doing something wrong or the API doesn't support and $in query of type ObjectId. Any ideas?
Your ids should be of type org.bson.types.ObjectId so something like this should work:
import org.bson.types.ObjectId;
ObjectId[] ids = new ObjectId[]{
new ObjectId("1234568abcd"),
new ObjectId("1234567abcd")};
DBObject query = QueryBuilder.start("app_id").in(ids)
.and("removed").is(false).get();