i want to merge some data in Elasticsearch, but every time it is replacing my previous data and not merging it.
Suppose when i new is created it should add with the previous data, not replacing previous data. So Suppose there is a user exists in the "update_field" named "Christofer" so when i array_merge($usernames) where $usernames contains one or couple of usernames it is always replacing previous data.
I am working on PHP.
$usernames= array ("Johanna", "Maria");
$doc = array();
$doc['update_field'] = array_merge($usernames);
$u_params = array();
$u_params['id'] = 'my_id';
$u_params['index'] = 'my_index';
$u_params['type'] = 'my_type';
$u_params['body'] = array('doc' => $doc);
$client->update($u_params);
For being more clear, as a example let's say in the usernames field there are couple of username exists- like - "Christofer", "Henrik", "Eric".
So now i want to add more user like - "Johanna", "Maria", ...
Now every time i merge and update documents it is replacing the data, like ("Christofer", "Henrik", "Eric") is getting replace by ("Johanna", "Maria").
I want them to be added not replaced.
Do any body knows how can i merge the new data, or just the new data in other process. Thanks in advanced.
You need to use partial update. Try this instead, i.e. you need to send a doc hash in the body with the fields to marge (i.e. update_fields):
$params = [
'index' => 'my_index',
'type' => 'my_type',
'id' => 'my_id',
'body' => [
'doc' => [
'update_field' => array_merge($usernames)
]
]
];
$client->update($params);
UPDATE
That's right, core values and arrays are getting replaced.
You may want to try scripted partial update then
$usernames= array ("Johanna", "Maria");
$script = array();
$script['script'] = 'ctx._source.update_field += new_value';
$script['params'] = array('new_value' => array_merge($usernames));
$u_params = array();
$u_params['id'] = 'my_id';
$u_params['index'] = 'my_index';
$u_params['type'] = 'my_type';
$u_params['body'] = $script;
$client->update($u_params);
And make sure that scripting is enabled in your elasticsearch.yml config file:
script.disable_dynamic: false
Related
I am using aws-php-sdk with dynamoDB to store a set of unique numerical values for a key.
I want to be able to append a new value to the set - this is easy to achieve with a list however this also results in duplicate values so I would rather use a set.
Because of the way dynamoDB is charged I don’t want to have to read all the values, insert unique value and write the whole set back because that would be very costly when scaled out. Docs seem to suggest appending to a number set is possible but doesn’t give much help in making it work.
$UpdateExpression = "
SET #subscribers = list_append(if_not_exists(#subscribers, :empty_list), :subscriber)
";
// This condition should match if the value already exists.
$ConditionExpression = "not contains (#subscribers,:subscriberStr)";
$ExpressionAttributeNames = [
"#subscribers" => "subscribers"
];
$ExpressionAttributeValues = $marshaler->marshalJson('
{
":subscriber": ['.$subscriber.'],
":empty_list": [],
":subscriberStr": "'.$subscriber.'"
}
');
$tableName = 'publisherRelationships';
$key = $marshaler->marshalJson('
{
"publisher": '.$publisher.'
}
');
$params = [
'TableName' => $tableName,
'Key' => $key,
'UpdateExpression' => $UpdateExpression,
'ConditionExpression' => $ConditionExpression,
'ExpressionAttributeNames' => $ExpressionAttributeNames,
'ExpressionAttributeValues' => $ExpressionAttributeValues
];
$result = $client->updateItem($params);
I've an existing form which is passing the input data to the model in an array format. $postdata has all the data from the view and sending to model.
Controller:
$inquiry_id = $this->input->post('inquiry_id');
$postdata = $this->input->post();
$this->load->model('Design_model');
$this->Design_model->insertdata($postdata,$inquiry_id);
Model:
function insertdata($data = array(), $inquiry_id){
$sql = $this->db->query("select * from design where inquiry_id='".$inquiry_id."'");
if($sql->num_rows() == 0){
$sql_query = $this->db->insert('design', $data);
}
else{
$this->db->where('inquiry_id', $inquiry_id);
$this->db->update('design', $data);
}
}
Above is working fine. Now, I'd like to add few fields in the view and save in a different database table. Need to exclude the new field values from $postdata array getting saved. Need to find the best approach to do this. I can start with some name for all the new fields, so that we can add any filter if available to exclude from the $postdata.
You can use elements() function from Array helper.
$array = array(
'id' => 101,
'title' => 'example',
'desc' => 'something',
'unwanted' => 'bla bla'
);
$filtered_array = elements(array('id','title','desc'),$array); //you can use this directly to the post data
$this->Design_model->insertdata($filtered_array,$inquiry_id);
You can use array_merge() or array_push() functions to add new fields to the array.
Let's say you have following data
$postdata = array("name"=>"xyz",
"email"=>"xyz#gmail.com",
"age"=>"40",
"gender"=>"Male",
"occupation"=>"Engineer"
);
Of which first 3 records are from old fields and last 2 are from new fields as you saying.
You need to find last index of first set i.e. '3' Now you can do this.
$firstDb = array_splice($postdata,0,3); //here 3 is index we are using to get first 3 records from $postdata
$secondDb = array_slice($postdata,0,3); //here 3 is index we are using to get records from position 3 from $postdata
Output:
$firstDb = array("name"=>"xyz","email"=>"xyz#gmail.com","age"=>"40");
$secondDb = array("gender"=>"Male","occupation"=>"Engineer");
Now you can insert you records as you wish to. Happy coding
I am using the Firebase PHP Admin SDK: https://firebase-php.readthedocs.io/en/stable/realtime-database.html#update-specific-fields
Here is the example it gives to update specific fields:
$uid = 'some-user-id';
$postData = [
'title' => 'My awesome post title',
'body' => 'This text should be longer',
];
// Create a key for a new post
$newPostKey = $db->getReference('posts')->push()->getKey();
$updates = [
'posts/'.$newPostKey => $postData,
'user-posts/'.$uid.'/'.$newPostKey => $postData,
];
$db->getReference() // this is the root reference
->update($updates);
From that, I created a users class and in that I have an update function. Like so:
public function update() {
$data = array('users' => array('1' => 'David'));
$this->database->getReference()->update($data);
return true;
}
In my database I have this structure:
Now if I run that function $users->update();
It removes the other child and only leaves David. Like so:
How can I update only a specific value of a specified key without it overriding the other data?
There's nothing specific to PHP here. That's the way Realtime Database update operations work. If you want a minimal update, you have to target the deepest key that you want to update. In your case, since you're storing an array type object, the keys are the number indexes of the array items you've written. If you want to modify one of them, you need to build a reference that includes the child number you want update. In that case, none of the sibling values will be touched.
Try this instead:
$this->database->getReference('users')->update(array('1' => 'David'));
Notice here that the update is rooted at "users", and you're updating just the immediate child "1" of that.
The example on docs is a little bit hard to grasp as a beginner. I have made it simpler for you to understand.
Once you get the newPostKey, prepare the url for child and run the code. It will only change the specific fields.
$ref = 'users/' . $newPostKey;
$updates = [
'title' => 'Updated title',
'body' => 'Updated body text',
];
$set = $db->getReference($ref)->update($updates);
In Laravel, I'm trying to create an array of some existing values I have that are built from values from a JSON object.
I have the 4 variables set and they dump properly but I'd like to add all 4 (username, perms, roles, access) to the array (IdentifierArray) with their own key/name so that when I add the array to the session and inspect it, I can see each value with it's key/name.
Code at this point:
$IdentifierArray = [];
$Username = $login->username;
$Perms = $login->permissions;
$Roles = $login->roles;
$Access = $login->access;
Session::put('Array of Values', $identifierArray);
So I'd like to add those object values to the array in the best way while having a key for each as well, like:
Array(
"username": $username value,
"perms":$perms value,
"Roles":$roles value,
"Access":$Access value
)
Another way of doing it, equal to #danboh:
$IdentifierArray = [
"username" => $login->username,
"permissions" => $login->permissions,
"roles" => $login->roles,
"access" => $login->access
];
Why not use a regular PHP array? Like:
$IdentifierArray["username"] = $login->username;
$IdentifierArray["permissions"] = $login->permissions;
$IdentifierArray["roles"] = $login->roles;
$IdentifierArray["access"] = $login->access;
You can use the array_only helper to make your life easy:
$identifierArray = array_only(
json_decode($login, true),
['username', 'permissions', 'roles', 'access']
);
Another option would be to use the only() Collection method:
collect(json_decode($login, true))
->only(['username', 'permissions', 'roles', 'access'])
->all();
Usually when I search for one related ID I do it like this:
$thisSearch = $collection->find(array(
'relatedMongoID' => new MongoId($mongoIDfromSomewhereElse)
));
How would I do it if I wanted to do something like this:
$mongoIdArray = array($mongoIDfromSomewhereElseOne, $mongoIDfromSomewhereElseTwo, $mongoIDfromSomewhereElseThree);
$thisSearch = $collection->find(array(
'relatedMongoID' => array( '$in' => new MongoId(mongoIdArray)
)));
I've tried it with and without the new MongoId(), i've even tried this with no luck.
foreach($mongoIdArray as $seprateIds){
$newMongoString .= new MongoId($seprateIds).', ';
}
$mongoIdArray = explode(',', $newMongoString).'0';
how do I search '$in' "_id" when you need to have the new MongoID() ran on each _id?
Hmm your rtying to do it the SQL way:
foreach($mongoIdArray as $seprateIds){
$newMongoString .= new MongoId($seprateIds).', ';
}
$mongoIdArray = explode(',', $newMongoString).'0';
Instead try:
$_ids = array();
foreach($mongoIdArray as $seprateIds){
$_ids[] = $serprateIds instanceof MongoId ? $seprateIds : new MongoId($seprateIds);
}
$thisSearch = $collection->find(array(
'relatedMongoID' => array( '$in' => $_ids)
));
That should produce a list of ObjectIds that can be used to search that field - relatedMongoID.
This is what I am doing
Basically, as shown in the documentation ( https://docs.mongodb.org/v3.0/reference/operator/query/in/ ) the $in operator for MongoDB in fact takes an array so you need to replicate this structure in PHP since the PHP driver is a 1-1 with the documentation on most fronts (except in some areas where you need to use an additional object, for example: MongoRegex)
Now, all _ids in MongoDB are in fact ObjectIds (unless you changed your structure) so what you need to do to complete this query is make an array of ObjectIds. The ObjectId in PHP is MongoId ( http://php.net/manual/en/class.mongoid.php )
So you need to make an array of MongoIds.
First, I walk through the array (could be done with array_walk) changing the values of each array element to a MongoId with the old value encapsulated in that object:
foreach($mongoIdArray as $seprateIds){
$_ids[] = $serprateIds instanceof MongoId ? $seprateIds : new MongoId($seprateIds);
}
I use a ternary operator here to see if the value is already a MongoId encapsulated value, and if not encapsulate it.
Then I add this new array to the query object to form the $in query array as shown in the main MongoDB documentation:
$thisSearch = $collection->find(array(
'relatedMongoID' => array( '$in' => $_ids)
));
So now when the query is sent to the server it forms a structure similar to:
{relatedMongoId: {$in: [ObjectId(''), ObjectId('')]}}
Which will return results.
Well... I came across the same issue and the solution might not be relevant anymore since the API might have changed. I solved this one with:
$ids = [
new \MongoDB\BSON\ObjectId('5ae0cc7bf3dd2b8bad1f71e2'),
new \MongoDB\BSON\ObjectId('5ae0cc7cf3dd2b8bae5aaf33'),
];
$collection->find([
'_id' => ['$in' => $_ids],
]);