I want to insert data in Mongo database
using PHP script, in year
wise documents so that it may look like this (All years in one document);
cars{
2017{
car=Motorolla
color = blue
}
2016{
car=Toyota
color = green
}
2015{
car=Corolla
color = black
}
}
I wanted to add the document but it prompts
Document can't have $ prefixed field names: $years[0]
Is it possible to make such schema in Mongo using PHP?
Code
<?php
try {
$car = 'Motorolla';
$color = 'blue';
//$car = 'Toyota';
//$color = 'green';
//$car = 'Corolla';
//$color = 'black';
$years = array(2017, 2016, 2015);
$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$bulkWriteManager = new MongoDB\Driver\BulkWrite;
$document = ['_id' => new MongoDB\BSON\ObjectID, '$years[0]' => $car, '$years[1]' => $color]; // Making a query type
try {
$bulkWriteManager->insert($document); // Inserting Document
echo 1;
} catch(MongoCursorException $e) {
/* handle the exception */
echo 0;
}
$manager->executeBulkWrite('dbName.carsCol', $bulkWriteManager); // Going to DB and Collection
} catch (MongoDB\Driver\Exception\Exception $e) {
$filename = basename(__FILE__);
echo "The $filename script has experienced an error.\n";
echo "It failed with the following exception:\n";
echo "Exception:", $e->getMessage(), "\n";
}
?>
I do not want to add whole car object at once. I want to add Year object
every time. Any help will be appreciable.
OR
Any relative answer so that I may get the data from Mongo Database
according to the year?
Edit1
For first time creation. - Credits goes to @Veeram
<?php
try {
$car = 'Malibu';
$color = 'red';
$years = array(2017);
$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$bulkWriteManager = new MongoDB\Driver\BulkWrite;
//{"car":"chevy", "color":"black", year: 2017}
$insert = ['car' => $car, 'color' => $color, 'year' => $years[0]];
try {
$bulkWriteManager -> insert($insert); // Inserting Document
echo 1;
} catch (MongoCursorException $e) {
echo 0;
}
$manager->executeBulkWrite('dbName.mycol', $bulkWriteManager); // Going to DB and Collection
} catch (MongoDB\Driver\Exception\Exception $e) {
$filename = basename(__FILE__);
echo "The $filename script has experienced an error.\n";
echo "It failed with the following exception:\n";
echo "Exception:", $e->getMessage(), "\n";
echo "In file:", $e->getFile(), "\n";
echo "On line:", $e->getLine(), "\n";
}
?>
For the updation- Credits goes to @Veeram
<?php
try {
$car = 'ChangedCar';
$color = 'changedColor';
$years = array(2017);
$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$bulkWriteManager = new MongoDB\Driver\BulkWrite;
$query = ['cars.year' => $years[0]];
//{ $push: { "cars.$.data": { "car":"chevy", "color":"black"} }}
$update = ['$push'=> ['cars.$.data'=>['car' => $car, 'color' => $color]]];
try {
$bulkWriteManager->update($query, $update); // Inserting Document
} catch(MongoCursorException $e) {
}
$manager->executeBulkWrite('dbName.mycol', $bulkWriteManager); // Going to DB and Collection
} catch (MongoDB\Driver\Exception\Exception $e) {
$filename = basename(__FILE__);
echo "The $filename script has experienced an error.\n";
echo "It failed with the following exception:\n";
echo "Exception:", $e->getMessage(), "\n";
}
?>
The problem in this code is that it successfully insert the data for the first time but when i update the data it does not update it.
Example:
There is a document named as cars
. Insert the data with object of year in one document. Let's say the Object is 2017, it contains color and car Model. As showing below; (Multiple objects with years. Year is unique in whole document.)
cars{
2017{
car=Motorolla
color = blue
}
2016{
car=Toyota
color = green
}
2015{
car=Corolla
color = black
}
}
If I want to update just make an object of 2017
like 2017{car=Updated-Motorolla color =Updated-blue}
and insert in the document. It should update only the year 2017 object in side the document.
cars{
2017{
car=Updated-Motorolla
color =Updated-blue
}
2016{
car=Toyota
color = green
}
2015{
car=Corolla
color = black
}
}
You can try something like this. Its not possible to perform all the Mongo db operations just based off key as a value.
The first solution is written to stay close to OP's design.
Assuming you can add a key to the year
.
{
"cars": [{
"year": "2017",
"data": [{
"car": "Motorolla",
"color": "blue"
}]
}, {
"year": "2016",
"data": [{
"car": "Toyota",
"color": "green"
}]
}]
}
Makes it easy to reference the year by its value.
For example to add a new value into the data
array for year
2017. You can try the below code.
Uses update positional $ operator.
query
part to reference the array where 2017 record is stored.
update
part using push
to add the new car
record to the existing data
array for 2017
row.
<?php
try {
$car = 'Malibu';
$color = 'blue';
$years = [2017];
$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$bulkWriteManager = new MongoDB\Driver\BulkWrite;
//{"cars.year":2017}
$query = ['cars.year' => $years[0]];
//{ $push: { "cars.$.data": { "car":"chevy", "color":"black"} }}
$update = ['$push'=> ['cars.$.data'=>['car' => $car, 'color' => $color]]];
try {
$bulkWriteManager->update($query, $update); // Update Document
echo 1;
} catch(MongoCursorException $e) {
/* handle the exception */
echo 0;
}
$manager->executeBulkWrite('dbName.carsCol', $bulkWriteManager); // Going to DB and Collection
} catch (MongoDB\Driver\Exception\Exception $e) {
$filename = basename(__FILE__);
echo "The $filename script has experienced an error.\n";
echo "It failed with the following exception:\n";
echo "Exception:", $e->getMessage(), "\n";
}
?>
For accessing data by year you can run below query.
Use query positional $
operator to find the array index using the query part and reference that value in projection part.
db.collection.find({"cars.year":2017}, {"cars.$.data":1});
Alternative Solution :
This will take care of everything as just inserts
You are better off saving each car entry in its own document.
{ "year" : 2017, "car" : "Motorolla", "color" : "blue" }
{ "year" : 2016, "car" : "Toyota", "color" : "green" }
{ "year" : 2015, "car" : "Corolla", "color" : "black" }
For each entry you can use:
db.collection.insert({"year":2017, "car":"Motorolla", "color":"blue"});
PHP Code:
//{"car":"chevy", "color":"black", year: 2017}
$insert = ['car' => $car, 'color' => $color, 'year' => $years[0]];
try {
$bulkWriteManager - > insert($insert); // Inserting Document
echo 1;
} catch (MongoCursorException $e) {
/* handle the exception */
echo 0;
}
For access data by year you can use
db.collection.find({"year":2017});
Updated PHP code:
<?php
try {
$cars = ['Motorolla','Toyota', 'Corolla'] ;
$colors = ['blue', 'green', 'black'];
$years = [2017, 2016, 2015];
$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$bulkWriteManager = new MongoDB\Driver\BulkWrite;
$query1 =["year" => $years[0]];
$query2 =["year" => $years[1]];
$query3 =["year" => $years[2]];
$update1 = ['$set' => ['car' => $cars[0], 'color' => $colors[0]]];
$update2 = ['$set' => ['car' => $cars[1], 'color' => $colors[1]]];
$update3 = ['$set' => ['car' => $cars[2], 'color' => $colors[2]]];
try {
$bulkWriteManager->update($query1, $update1, ["upsert" => true]);
$bulkWriteManager->update($query2, $update2, ["upsert" => true]);
$bulkWriteManager->update($query3, $update3, ["upsert" => true]);
echo 1;
} catch(MongoCursorException $e) {
/* handle the exception */
echo 0;
}
$manager->executeBulkWrite('dbName.carsCol', $bulkWriteManager); // Going to DB and Collection
} catch (MongoDB\Driver\Exception\Exception $e) {
$filename = basename(__FILE__);
echo "The $filename script has experienced an error.\n";
echo "It failed with the following exception:\n";
echo "Exception:", $e->getMessage(), "\n";
}
?>
You can perform complex queries using aggregation pipeline and you can add index to make your response quicker.
Observations:
First Solution : Harder to update/insert data, but keeps everything together so easier to read data.
Second Solution : Cleaner and simpler to do CRUD operations on documents and use aggregation pipeline to preform complex queries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With