You can try something like this. It is not possible to perform all Mongo db operations based only on the key value.
The first solution is written to stay close to the OP design.
Assuming you can add a key to year
.
{ "cars": [{ "year": "2017", "data": [{ "car": "Motorolla", "color": "blue" }] }, { "year": "2016", "data": [{ "car": "Toyota", "color": "green" }] }] }
Allows you to easily refer to the year by its value.
For example, to add a new value to the data
array for year
2017. You can try the code below.
Uses the update positional $ operator.
query
to reference the array in which the 2017 record is stored.
update
, using push
to add a new car
entry to the existing data
array for row 2017
.
<?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"; } ?>
To access the data by year, you can complete the request below.
Use positional $
query to find the index of the array using the query part and a reference to this value in the projection part.
db.collection.find({"cars.year":2017}, {"cars.$.data":1});
Alternative solution:
This will take care of everything as soon as it inserts
You better keep a record of each car in your 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; }
To access data for the 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) { echo 0; } $manager->executeBulkWrite('dbName.carsCol', $bulkWriteManager);
You can perform complex queries using the aggregation pipeline, and you can add an index to respond faster.
Remarks:
First decision . It is more difficult to update / insert data, but all this makes reading data easier.
Second solution : Itβs cleaner and easier to perform CRUD operations on documents and use the aggregation pipeline to create complex queries.