How to build an $in query of ObjectIds using QueryBuilder with MongoDB - mongodb

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();

Related

mongo group with match query does not work with java

I have below query working in robo 3T console.
db.metrics.aggregate([
{'$match':{'status':'SUCCESS'}},
{'$group':{ _id:'$bapiName',count:{$sum:1}}}
])
But when I execute it with java,
MongoCollection collection =db.getCollection();
List<Bson> pipeLine = new ArrayList<Bson>();
pipeLine.add(Document.parse("{'$match':{'status':'SUCCESS'}}"));
pipeLine.add(Document.parse("{'$group' : {_id: {bapiName:'$bapiName',status:'$status'}, count:{$sum:1}}}"));
Iterator iterator = collection.aggregate(query.getPipeline()).iterator();
while( iterator.hasNext()) {
Object object = iterator.next();
resultList.add((Document)object);
System.out.println(" class "+object.getClass()+" data "+object);
}
I am not getting the results. Iterator is empty. Any changes need to be made in java to get it working?

$elemMatch and $eq equivalent in spring data mongodb

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)

Will upsert work with array Elements as well as the normal ID in MongoDB through Java driver

Mongo DB contains the following data:
The requirement is if inside this document an Field exists incremnt the counter else insert the field.
Generally we use upsert for situations when we are not sure if its going to be insert or Update.But will this work with
array Elements as well
db.arrayexample.find()
{ "_id" : "userID", "addresses" : [ { "arrayid" : NumberLong(16694), "count" : 12 } ] }
My Java code is as follows:
MongoClient mongoClient = new MongoClient("localhost", 27017);
MongoDatabase mongoDatabase = mongoClient.getDatabase("testdb3");
MongoCollection mongoCollection = mongoDatabase.getCollection("arrayexample");
BasicDBObject query = new BasicDBObject();
query.put("_id", "userID");
query.put("addresses.arrayid",Long.valueOf(16695) );
mongoCollection.findOneAndUpdate(query,new Document("$inc", new Document("addresses.$.count", 1)),new FindOneAndUpdateOptions().upsert(true));
I am getting the following error when i run the Program:
'exception: Cannot apply the positional operator without a corresponding query field containing an array.' on server localhost:27017. The full response is
"value" : null, "errmsg" : "exception: Cannot apply the positional operator without a corresponding query field containing an array.", "code" : 16650,
Will $Upset work with array Elements as well as the normal ID
No, upserts will not work when using the $positional operator, as noted in the MongoDB documentation.
http://docs.mongodb.org/manual/reference/operator/update/positional/#upsert
Edit: As some flavour, it appears that there is an open feature request to support this particular kind of update when combined with the $setOnInsert operator within MongoDB's Jira https://jira.mongodb.org/browse/SERVER-10711

MongoDB: $in with an ObjectId array

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)}) } } })

Doctrine QueryBuilder don't working with DBRef

I currently have a field on a document of the posts collection which is a ReferenceOne to a collection of users. Querying on the shell db.posts.findOne({"usuario_stream.$id": ObjectId("5012d7674dfbad7f4e000084")}) works fine, but using the QueryBuilder it simply doesn't works.
$this->doctrine->createQueryBuilder('Documents\Posts')->field('usuario_stream.$id')->equals(new MongoId('5012d7674dfbad7f4e000084'))->eagerCursor(true)->getQuery()->execute(); on profiler shows { "$query" : { "usuario_stream.$id" : null }, "$orderby" : [ ] }.
I'm doing anything wrong?
It should work if you query on usuario_stream.$id using the ID as a string rather than an instance of MongoID:
->field('usuario_stream.$id')->equals('5012d7674dfbad7f4e000084')