How to find by referenced document in Doctrine ODM with MongoDB? - mongodb

I have one document in my "params" collection like this:
{
"_id": ObjectId("4d124cef3ffcf6f410000037"),
"code": "color",
"productTypes": [
{
"$ref": "productTypes",
"$id": ObjectId("4d120a2d2b8d8d3010000000"),
"$db": "test"
}
]
}
the referenced document is this:
{
"_id": ObjectId("4d120a2d2b8d8d3010000000"),
"code": "car"
}
I'm using DoctrineODM to fetch the "param" documents which referenced "productType" is "car". I'm using this code:
$query = $dm->createQuery('Cms\Model\Param');
$query->field('productTypes.code')->equals('car');
$result = $query->execute();
var_dump($result);
but the result is an empty array. How can i do this?

If you using ReferenceMany or ReferenceOne you can't query by any reference document field, except reference document id.
If you need query on code from referenced collection you should use EmbedMany instead of ReferenceMany.
In this case your document will be:
{
"_id": ObjectId("4d124cef3ffcf6f410000037"),
"code": "color",
"productTypes": [
{
"_id": ObjectId("4d120a2d2b8d8d3010000000"),
"code": "car"
}
]
}
And following query will work:
$query = $dm->createQuery('Cms\Model\Param');
$query->field('productTypes.code')->equals('car');
$result = $query->execute();
var_dump($result);
Also if your ProductType code is unique you can use it instead of MongoId, in this case you can query on $id:
{
"_id": ObjectId("4d124cef3ffcf6f410000037"),
"code": "color",
"productTypes": [
{
"$ref": "productTypes",
"$id": 'car',
"$db": "test"
}
]
}
Referenced document:
{
"_id": 'car'
}
Query:
$query->field('productTypes.$id')->equals('car');

You must use the references() method of Query Builder for a #MongoDB\ReferenceOne like https://doctrine-mongodb-odm.readthedocs.org/en/latest/reference/query-builder-api.html
$productType = $dm->getRepository('Cms\Model\ProductTypes')->findOneByCode('car');
$queryBuilder = $dm->getRepository('Cms\Model\Param')->createQueryBuilder()
->field('productTypes')->references($productType);
$results = $queryBuilder->getQuery()->execute();
PS: use includesReferenceTo() a #MongoDB\ReferenceMany

->field('productTypes.code')->equals(new \MongoRegex('/.*car.*/i'))

Related

Flask-PyMongo DBRef is not working as expected

How can I define ref and how to query a collection with ref populating related fields.
I defined a ref when inserting a product document in a product collection, but when querying I am getting info as inserted without populating the category field. I am expecting the mongo to populate category field with category document in category collection. The following are some code snippets:
Document Insertion:
category = "5126bc054aed4daf9e2ab772"
product_name = "Prod"
new_product_id = mongo.db.product.insert_one({
"product_name": product_name,
"category": {
"$ref": "category",
"$id": ObjectId(category)
}
}).inserted_id
Results Obtained:
{
"_id": {
"$oid": "61dd1612b898afc16e0f4325"
},
"category": {
"$id": {
"$oid": "5126bc054aed4daf9e2ab772"
},
"$ref": "category"
},
"product_name": "Prod"
}
I think you can try the below code, I feel it will work
category = "5126bc054aed4daf9e2ab772"
product_name = "Prod"
new_product_id = mongo.db.product.insert_one({
"product_name": product_name,
"category": category
}).inserted_id

How to search through a list of objects nested inside an array with Spring data MongoDB?

I have got a collection of documents and each documents contains a nested array of objects.
{
"id": "309324739",
"debters": [
{
"user": {
"name": "John Doe",
"internal": true
},
"debt": 1463,
},
{
"user": {
"name": "Alex Tree",
"internal": false
},
"debt": 53443,
},
}
What I'm trying to do is to return find the document by id and then find inside the debters list that has a false flag?
I tried the following query...
Debters findByIdAndDebters_User_InternalIsFalse(#Param("id") String id,);
But I'm getting an error saying that it can find "internal" property. What am I doing wrong and how can I loop through array using this magic mongo repository query?
you need to write a native query for that which is similar to
#Query("{'debters.user.internal':false,'_id':''}")
Debters findByIdAndDebtersUserInternalIsFalse(#Param("id") String id,);

how to update partial document of an array

i have a person document, that have list of pets:
{
"personId": "kjadfh97r0",
"pets": [
{
"petId": "dfjkh32476",
"name": "kitty",
"kind": "cat"
},
{
"petId": "askdjfh2794857",
"name": "rexy",
"kind": "dog"
}
]
}
I want to find certain pen inside of certain person and update just some fields, so I did something like:
db.people.findAndModify({
query: { "personId": "kjadfh97r0", "pets.petId": "dfjkh32476" },
update: {"$set":{"pets.$":{"kind":"tiger"}}}
})
but what happens to me is that the whole document is replaced with "kind":"tiger", and I just wanted to update the "kind" field any keep the rest.
You should specify entire path for $set when you update nested document using positional operator, otherwise the document will be replaced:
db.people.findAndModify({
query: { "personId": "kjadfh97r0", "pets.petId": "dfjkh32476" },
update: { $set: {"pets.$.kind": "tiger"} }
})

projection in php mongodb

I have a collection with document like
{
"_id": ObjectId("5b4dd622d2ccda10c00000f0"),
"Code": "Route-001",
"Name": "Karan Nagar - Jawahar Nagar",
"StopsDetails": [
{
"StopId": "cb038446-bbad-5460-79f7-4b138024968b",
"Code": "Stop- 001",
"Name": "Lane market",
"Fee": "600"
},
{
"StopId": "2502ce2a-900e-e686-79ea-33a2305abf91",
"Code": "Stop-002",
"Name": "City center",
"Fee": "644"
}
],
"StopsTiming" :
[
....
]
}
I want to fetch all embedded documents "StopDetails" only. I am trying to tweak below lines of codes but I am not able get what to write in $query "StopsDetails" in order to fetch only StopsDetails embedded document.
Please help !!!
$query = ['_id' => new MongoDB\BSON\ObjectID($this->id),
'StopsDetails' => ];
try
{
$cursor = $this->collection->find($query);
}
catch (Exception $e)
{
}
return $cursor->toArray();
You need to use projection in the second parameter of the query
$query = ['_id' => new MongoDB\BSON\ObjectID($this->id)]
$projection = ['StopsDetails' => true]
$cursor = $this->collection->find($query, $projection);
which is similar to the javascript query
db.collection.find({ '_id': ObjectId }, { 'StopDetails': 1 })
YourModel.findOne({_id:yourId},function(err,result){
console.log(result); //will return all data
console.log(result.StopsDetails); //will retrun your stop details
}
If you want to fetch specific embedded fields in MongoDB you can use projection
Projection
Try it mongodb playground
db.col.find({"_id" : ObjectId("5b4dd622d2ccda10c00000f0")},{"StopsDetails" : 1});

How to update names field nested in an array in mongodb

I have this object and I'd like to update the name field "field" of all the document in the collections. I read the mongodb documentation and it says $rename doesn't work in this case. I should execute a forEach but I don't know how which command use
{
"name": "foo"
"array": [
"object": {
"field": "name"
}
]
}
Do it manually:
db.collection.find().forEach(function(doc) {
if (doc.array) {
doc.array.forEach(function(edoc) {
if (edoc.object) {
doc.object.new_field = edoc.object.field
delete edoc.object.field
}
})
db.test.update({ "_id" : doc._id }, doc)
}
})
This should get you started. It handles missing or empty array arrays, but not an array value of the wrong type, or an object value of the wrong type.
$rename modifier for update Ops should work (http://docs.mongodb.org/manual/reference/operator/update/rename/)
Imagine a collection like yours:
{
"name": "foo",
"array":[
{"field": "name" }
]
}
You will be able to do something like this:
db.rename.update({},{$rename:{"name":"newName"}});
And the document will be as follows:
{
"newName": "foo",
"array":[
{"field": "name" }
]
}
In order to update all the collection you should use the multi option as follows:
db.rename.update({},{$rename:{"name":"newName"}}, {multi:true})
Regards