MongoDB: merge raw object into nested structure - php

I have an array object like this:
[
'things'=>[
't1'=>[ 'prop1'=>3 ]
]
]
and I want to merge it into the following collection entry:
[
'id'=>123,
'things'=>[
't1'=>[ 'prop1'=>1, 'prop2'=>2 ],
't2'=>[ 'prop1'=>1, 'prop2'=>2 ]
]
]
If I try to use the object as is, the following code deletes things.t1.prop2 and things.t2:
$db_collection->update([ 'id'=>123 ], [ '$set'=>[ 'things'=>[ 't1'=>[ 'prop1'=>3 ] ] ] ]);
Probably I have to convert the object into the dot notation format like this:
$db_collection->update([ 'id'=>123 ], [ '$set'=>[ 'things.t1.prop1'=>3 ] ]);
I can also read the whole entry first, merge data with a specific function inside my script, and write the updated entry back into the database.
But these ways don't seem to be very efficient. Is there a special command in Mongo to incorporate a raw object into nested data without overwriting the whole entry?
P.S.: I'm using a PHP MongoDB driver.

Related

php class in an array

I have a php file where I have an array with some data in classes like this: (in javascript)
array = [
{engine: "V6",
capacity: 2.5,
hp: 300
}]
I tried to put this into a php file but it gave me 500 error
$array = [{engine => "V6",
capacity=> 2.5,
hp=> 300}];
I think I may be doing something wrong over here, could someone confirm?
You can't just translate JavaScript code into PHP without understanding the syntax of both languages.
In JavaScript, this creates an array containing an object:
var array = [
{
engine: "V6",
capacity: 2.5,
hp: 300
}
]
In PHP, the common equivalent would be an array containing another (associative) array, which would be written like this:
$array = [
[
'engine' => "V6",
'capacity' => 2.5,
'hp' => 300
]
];
As an aside, since it's been mentioned elsewhere on this page, you could also write the same thing in JSON like this:
[
{
"engine": "V6",
"capacity": 2.5,
"hp": 300
}
]
If you called JSON.stringify(array) in JavaScript, or json_encode($array) in PHP, that's how the JSON string you'd get would look.
The JSON looks very similar to the JavaScript, because JSON's syntax was based on JavaScript's. In fact, the above would be valid JavaScript code, and you can use (arguably, abuse) json_encode as a way to generate JavaScript code using PHP.
Note that none of these contains any kind of "class" - a class is a way of defining a type of object, from which you want to make several instances.
You are mixing PHP with JSOL or JSON. PHP doesn't read JSOL nor JSON natively.
<?php
$array = [
[
'engine' => 'V6',
'capacity' => 2.5,
'hp' => 300
],
];
echo json_encode($array);
See https://3v4l.org/5b9V1

Unable to find index for $geoNear Laravel

I am using the Moloquent model with Laravel 5.6. here is my collection record given below:-
{
"_id" : ObjectId("5afe619dbe0b8d0e5876b16b"),
"name" : "Central Park",
"categories" : [
"4d4b7105d754a06376d81259",
"4bf58dd8d48988d116941735",
"4bf58dd8d48988d119941735",
"4d4b7105d754a06376d81259",
"4bf58dd8d48988d116941735",
"4bf58dd8d48988d119941735",
"4d4b7105d754a06374d81259",
"4bf58dd8d48988d16d941735"
],
"loc" : {
"type" : "Point",
"coordinates" : [
88.4166612820784,
22.5835157504658
]
}
}
I am running this query from the Laravel controller.
$users = MongoTest::where('loc', 'near', [
'$geometry' => [
'type' => 'Point',
'coordinates' => [
$longitude,
$latitude,
],
],
'$maxDistance' => 10,
])->get();
print_r($users);
I am getting this error:-
error processing query: ns=tkit.testTree: GEONEAR field=loc maxdist=10 isNearSphere=0
Sort: {}
Proj: {}
planner returned error: unable to find index for $geoNear query
How can I solve this?
Create an index from the mongo shell. A 2sphere index is expected by the query using the $near or $nearSphere operator or geoNear command, or even the $geoNear aggregation pipeline stage.
The createIndex() method will do this for you, so just name your collection within the correct database:
db.collection.createIndex({ "loc": "2dsphere" })
Note that any API actually using the geoNear command really needs to update to one of the other mentioned query operators as this command is "deprecated" from MongoDB 4.0 onwards and will be removed.
Operations looking for "nearest" should use $near or $nearSphere, and those which want to return the "distance" should use the $geoNear pipelie stage instead.

Get form/fieldset element name inside custom validator class in ZF3

I created my custom validator class that implemented ValidatorInterface. How to get element name of the fieldset or form that is validated?
I need this inside the validator class.
I am going to do some validating logic inside the class validator cause I am going to use the context array with all values and distinguish which is the current one.
Nope you can't. But you can use callable filter to re-design your value. I don't know if it's reasonable way to do it. I didn't face such a problem like this. But here's an example
$this->add([
/** other settings **/
"filters" => [
[
"name" => \Zend\Filter\Callable::class,
"options" => ["callback" => function($value){
return "fieldset-x:".$value;
}]
]
],
"validators" => [
[
"name" => \Zend\Validator\Callable::class,
"options" => ["callback" => function($value){
/** algorithm: split via ":". first element is freamwork **/
}]
]
]
])
I used callable filter and validator to do is. You may want to write your own filter/validator.

Passing information to template from multiple databases with Laravel

I have to pass multiple databases info with Laravel. I always do this:
public function get_view(){
$myinfo = MyDatabases::where('id',Auth::user()->id)->get();
return view('auth.view')->with('myinfo',$myinfo);
}
I need to pass info from other databases. Is there a way to do this?
You have some db in your file app/config/database.php ?
'connections' => [
'mysql1' => [
],
'mysql2' => []
]
You can use :
\DB::connection('mysql1')->table()->where(....)
\DB::connection('mysql2')->table()->where(....)
and you can create some help function or Facade, where you can aggregate this queries

Mongodb document update error with Codeigniter: Mod on _id not allowed

I'm trying to use Codeigniter with codeigniter-mongodb-library/tree/v2 in order to connect with mongo and Update documents with this structure:
{
"_id" : ObjectId("50fd8bd460e958aa38000002"),
"created_at" : 1358793684,
"updated_at" : 1358793684,
"is_active" : 0,
"memberships" : [
{
}
],
"first_models" : [
[ ]
],
"second_models" : [
[ ]
],
"pages" : [
[ ]
]
}
All I want is Update some document by it's given _id. Particularly I need to add elements inside "first_models" array. From my Codeigniter model I'm calling this:
$result = $this->mongo_db
->push(array('_id' => '50fd8bd460e958aa38000002'),array('first_models' => array('Some text here')))
->update($this->collections['sites']);
I'm getting this error when I try to Update one specific document:
Mod on _id not allowed
Seems there is some conflict with the given _id... I'm missing something and I don't know what :(
I'm using Mongodb 2.2.2 with Codeigniter 2.1.3, PHP5.4 and Apache2.
I was going in wrong direction with that. Finally #Rajan points me to right solution:
$updated = $this->mongo_db->where('_id', new MongoId($id))
->set($data)
->update('mycollection');
You can see, using set instead push, and referencing object id with new MongoId($id) :-)

Categories