Doctrine QueryBuilder don't working with DBRef - mongodb

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

Related

Mongo Upsert $in values from Find That were Not found

I have to run mongo updates for employee id linked to a supervisorId (That's an oversimplification, but its the gist of what I need). The find uses a list of employee ids, and if the employee id is not found, I have an upsert to add the data. However the issue is I'm not getting the employee id in the upsert. Is it possible to upsert values from the $in array?
Eg:
db.collection.update({
empId:{
$in:['EMP1','EMP2','EMP3']
}
},
{$set: {SupervisorId:'SUP25'}},
{upsert:true},
{multi:true})
If I run this query I get one new doc with _id and SupervisorId:
{
"_id" : ObjectId("5e56ece8b0ae3537d0261ghg"),
"SupervisorId" : "SUP25"
}
I would like to get this in my upserts:
{
"_id" : ObjectId("5e56ece8b0ae3537d0261ghg"),
"SupervisorId" : "SUP25"
"EmpId": "EMP1"
}
I'm still getting comfortable with mongo, but is this even possible with an upsert? If not possible, are there any options for something similar?
MongoDB version 2.9.1

How do a query to find by Id using DBRef in MongoDB? [duplicate]

suppose I have the following datastructure:
var user = {_id: 'foo', age: 35};
var post = {_id: '...', author: {$ref: user, $id: 'foo'},...};
How can I query all posts which references user[foo]? I tried the following but not work:
db.post.find('author._id': 'foo');
var u = db.user.find({_id: 'foo'});
db.post.find('author': u);
neither can I find the answer from the official document and google!
Anyone has any idea?
Got it:
db.post.find({'author.$id': 'foo'})
This db.post.find('author.$id': 'foo') has missing the {}, so the correct sentence is:
db.post.find({'author.$id': 'foo'})
Also this can be achieved with:
db.post.find({'author': DBRef("user", ObjectId('foo'))})
But is more compact and practical the first way.
You can use the .$id reference but it will ignore any indexes on those fields.
I would suggest ignoring that method unless you are querying it directly via the terminal or want to look up something quickly. In using large collections you will want to index the field and query it using the below method.
If you want to use an index query using the following:
db.post.find('author' : { "$ref" : 'user', "$id" : 'foo' , "$db" :'database_name' })
If foo is an object id
db.post.find('author' : { "$ref" : 'user', "$id" : ObjectId('foo') , "$db" :'database_name' })
You can create an index on author by
db.post.ensureIndex( {'author' : 1 } );
For anyone looking for a Java solution to this then if you are using mongojack its really easy:
collection.find(DBQuery.is("user", new DBRef(user.getId(), User.class)));
Where collection is a JacksonDBCollection.
In mongoengine you should just use the instance of the referenced object. It should have the ID set.
Suppose the author is the Author document instance. So using this:
Post.objects(author__eq=author)
you can go through all posts of this author.
Post.author should be defined as ReferenceField
Using Mongo 2.4.1 version
This is how you do it on command line for OLA collection where #DBRef dbrefName
db.OLA.find({"dbrefName.someFieldValue" : "Personal"});
Exact query
db.OLA.find({"dbrefName.$id" : ObjectId("1234")});

Spring Data MongoDB find query returning no results

I have a mongodb collection with multiple documents of following structure
{
"_id" : "...",
"_class" : "...",
...
"travelers" : [
{
"id": "12345",
"type": "XYZ"
},
{
"id": "67890",
"type": "ABC"
}],
...
}
Using spring data, I am able to fetch documents that have traveler type XYZ :
Query query = new Query(Criteria.where("travelers.type").is("XYZ");
List<Something> something = mongoTemplate.find(query, Something.class, COLLECTION_NAME);
But if I switch the query to fetch by traveler id, I get no results:
Query query = new Query(Criteria.where("travelers.id").is("12345");
List<Something> something = mongoTemplate.find(query, Something.class, COLLECTION_NAME);
I enabled all logs and the outgoing query is {"travelers.id" : "12345"} which looks right. Running the query {"travelers.id" : "12345"} directly on the db returns the right results.
Other queries I have tried on the collection seem to work fine. I have tried both with & without index on travelers.id and no results in both cases. What am I doing wrong?
Fields with "id" name get special treatment in mapping - see http://docs.spring.io/spring-data/data-mongodb/docs/current/reference/html/#mongo-template.id-handling
What happens is that spring data mapping translates id to "_id" for your query when you do:
Query query = new Query(Criteria.where("travelers.id").is("12345");
so the query going to mongo isn't
{"travelers.id" : "12345"}
but is
{"travelers._id" : "12345"}
The queries logged by spring data mongo are little bit different to what actually goes to mongo.
Strange thing is that spring data doesn't do this mapping when saving the data.
Rename the id field to something like travelerId will solves the issue.

Update a Mongodb document and add fields

I'm trying to update a mongodb document and add some fields but in vain
my initial document looks like this
{"_id" : ObjectId("52c720e3211b6f0a258b4567"),
"email" : "someemail#msn.com",
"date" : ISODate("2014-01-03T20:43:15Z"),
"number" : 0, "accessToken" : "CAAIc2knVS3oBAAWRw5iqTK6mo6BEjwJJtT8PRZBUfhLayyelcXDZBO0pTWULGNPOZAxb9ZAwWk1oQghdcqxRr5yycMvkSokU7vYn3OWQJVWFuxbHC6L6F3NvLAYCrkoPvnoZAmNZBkkvG4qXFQT46hyPrDSc7GTZA1IpxVrQHEGbrwZDZD" }
After Update, I want to add 2 fields to the document which are : username and password.
I've looked into documentation but it doesn't seem to treat this matter.
Thanks a lot
If you're working with a doctrine ODM Document object :
$document->setUsername($username); // $document is your document instance
$document->setPassword($password);
$dm->flush($document); // $dm : document manager
If you want a standalone query (through QueryBuilder) :
$dm->createQueryBuilder('YourBundle:YourDocumentClass')
->field('_id')->Equals("52c720e3211b6f0a258b4567")
->update()
->field('username')->set($username)
->field('password')->set($password)
->getQuery()->execute();
More info and querybuilder examples here :
http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/query-builder-api.html
In the mongo shell you could do it like this:
db.myusers.update(
{_id: ObjectId("52c720e3211b6f0a258b4567")}, // identify document
{$set: {username: 'scott', password: 'tiger'} })
This leaves the other fields untouched.

How to query against ObjectId when not in mongo shell

I'm working on paging functionality using a range query. I'm using this test query in the mongo shell:
> var params = {$query: {_id: {$lt: ObjectId("52b06166eff887999c6efbd9")}}, $orderby: {_id: -1}, $maxScan: 3}
> params
{
"$query" : {
"_id" : {
"$lt" : ObjectId("52b06166eff887999c6efbd9")
}
},
"$orderby" : {
"_id" : -1
},
"$maxScan" : 3
}
> db.events.find(params)
I'd like to be able to pass the serialized params object to a web service (as a URL query string). However, the ObjectId class is only available inside the shell. Is there a way to specify an ObjectId as part of a query when not in the shell? I've tried the following as the value of $lt without success:
'ObjectId("52b06166eff887999c6efbd9")'
'new ObjectId("52b06166eff887999c6efbd9")'
{"$oid" : "52b06166eff887999c6efbd9"}
Generally speaking, this abstraction is handled by whatever MongoDB driver you use. If you are using an actual driver, you can do queries on _id without using ObjectId()
Mongoose / Node.js Example:
People.find({ _id : "Valid ObjectID String" }, function(e, person) {
console.log(e, person);
});
If you do still need the ObjectId helper, generally you are able to reference it in whatever native driver you need.
What you are doing in your last examples is passing your objectId as a string (first two examples) or as a dictionary third example. So surely it does not work.
You can pass just a string '52b06166eff887999c6efbd9' as a parameter and then when you receive it you can construct normal ObjectId on the server. For example in php you can construct it in the following way new MongoId('your string');