问题
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
}
}
回答1:
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.
回答2:
Try to change
$document = ['_id' => new MongoDB\BSON\ObjectID, '$years[0]' => $car, '$years[1]' => $color];
to something like:
$document = ['_id' => new \MongoDB\BSON\ObjectID, $years[0] => ['car' => $car, 'color' => $color]];
it gives such result in mongo:
{ "_id" : ObjectId("58a936ecfc11985f525a4582"), "2017" : { "car" : "Motorolla", "color" : "blue" }
If data about all cars must be in one document, you need to combine data fitst:
$cars = [
'2017' => [
'car' => 'Motorolla',
'color' => 'blue'
],
'2016' => [
'car' => 'Toyota',
'color' => 'green'
],
'2015' => [
'car' => 'Corolla',
'color' => 'black'
]
];
and than
$document = ['_id' => new \MongoDB\BSON\ObjectID, 'cars' => $cars];
It gives mongo document like:
{ "_id" : ObjectId("58aabc0cfc11980f57611832"), "cars" : { "2017" : { "car" : "Motorolla", "color" : "blue" }, "2016" : { "car" : "Toyota", "color" : "green" }, "2015" : { "car" : "Corolla", "color" : "black" } } }
来源:https://stackoverflow.com/questions/42299250/add-data-inside-documents-in-mongo-db-using-php