PHP DynamoDB- Add/Update an value in the list - php

I am trying to add more email address to the list. The architecture and the example in Dynamo DB
ID: STRING
DEP: MAP
Contacts: MAP
EMAIL: LIST
Version: Number
{
“ID”: "1234567888",
"Dep": {
"Contacts": {
"Email": [
"test#test.com”
]
}
},
"Version": 34
}
I tried but it just updates the value but don't add the new one. (if you can also help me with if the value does not exist than only add would be nice but not mandatory)
$eav = $marshaler->marshalItem([":email" => [$email]]);
$params = ['TableName' => "xxx", 'ID' => $key,
'UpdateExpression' => 'SET Dep.Contacts.Email = :email',
'ExpressionAttributeValues' => $eav, 'ReturnValues' => 'UPDATED_NEW'];
$result = $dynamodb->updateItem($params);

You should list_append to add an element to a list. CLI example below:
--update-expression "SET #ri = list_append(#ri, :vals)"
You can see this in the documentation here:
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.AddingListElements

Related

the match filter must be an expression in an object with mongo aggregation in PHP

So first here's what I'm trying to do :
I got a datatable with some custom inputs. Users can select skills (php, mysql etc) and the standard text input. Users can select multiple skills. When multiple skills are selected it's supposed to be kind of an AND AND query. So both skills must be available.
The standard text input in datatables would contain information such as the name of a customer, their email or job function.
For example I check PHP and Javascript, in my text search I put Google.
Which would mean I'm looking for a document which has both PHP and Javascript in the tags (Or any of their aliases eg: Javascript => js), and has google in any other field thats listed (Customer, function, sender name, sender email or subject).
But it should also be able to search for documents just matching the skills or only for the text input.
I have been trying to build arrays with all query options and merge those depending on input to the function but so far nothing has been working.
the match filter must be an expression in an object
So below is an example of a document I got in Mongo
{
"_id": {
"$oid": "superfancyID"
},
"parsed": {
"tags": [
"sql",
"php"
],
"customer": "CustomerName",
"function": "functionName",
"mail_properties": {
"senderName": "SenderName",
"senderEmail": "example#example.com",
"subject": "FW: Test email",
}
}
}
Here is some code I got to try and build my query
public function handler(int $skip, int $limit, array $filters, string $filterString = '') {
# $filters are skills
# $filterString is a string of everything else you put in the search field of the datatable
/** #var \MongoDB\Collection $collection */
$collection = $this->emailRepository->getCollection();
/** #var array $regex */
$regex = [];
if(!empty($filterString))
{
$strings = explode(' ', $filterString);
foreach($strings as $item)
{
$regex[] = new Regex($item, 'i');
}
}
#This function basically does the same as above.
#The only change is that this also goes over any aliases for skills. (Javascript => js)
/** #var array $aliasRegex */
$aliasRegex = $this->createAliasRegex($filters);
$skillsFilters = [];
#This is where I attempt to create a part of the query for just the skills.
if(!empty($aliasRegex)) {
$skillsFilters = [
'$and' => [
'$or' => [
['parsed.tags' => [
'$in' => $aliasRegex
]]
]
]
];
}
$stringFilters = [];
#This is where I try and build the rest of the query.
if(!empty($regex)) {
$stringFilters = ['$or' =>
['parsed.function' => [
'$in' => $regex
]],
['parsed.mail_properties.subject' => [
'$in' => $regex
]],
['parsed.customer' => [
'$in' => $regex
]]
];
}
$documents = $collection->aggregate([
[
'$match' => [
array_merge($stringFilters, $aliasFilters)
]
]
,[
'$limit' => $limit,
],[
'$skip' => $skip
]
]);
This is basically all I got, I tried checking my arrays and moving around some parts but nothing has been working for me. I always been getting back the error
the match filter must be an expression in an object

PHP/MongoDB, Unable to update records in a collection

I am trying to update records in a mongodb by using php codeigniter, but I am unable to do so.
My controller class:
function updatetodb_post(){
$updateddata = array('$set' => array("lang" => "English"));
$this->load->model('data_model');
$uid = 1;
$this->data_model->updaterecords($uid, $updateddata);
}
My Model class:
function updaterecords($uid, $updatedata){
$this->load->library('mongo_db');
$recoundsbyuid = $this->mongo_db->get_where($this->_testcollectoin, array("uid" => $uid));
$this->mongo_db->update($this->_testcollectoin, $recoundsbyuid, $updatedata);
}
data that I want to update in a collectoin:
$data = array(
"uid" => "1",
"type" => "Movie",
"genre" => "Action"
);
where _testcollectoinis my collection name. I want to add one more field (lang) to the array.
We can use below commands to update with given data
$this->mongo_db->where(array("uid" => $uid))->set($updatedata)->update($this->_testcollectoin);

Craft Element API data output as a hash instead of an array

I'm building and API feed using Element API plugin from Craft, and I'd like the data output to be serialized as a hash, but currently it's returning an array, as example bellow:
<?php
namespace Craft;
return [
'endpoints' => [
'event-name/feed.json' => [
'elementType' => ElementType::Entry,
'criteria' => ['section' => 'event1'],
'transformer' => function(EntryModel $entry) {
$speakersList = [];
foreach ($entry->speakersList as $speaker) {
$speakersList[] = [
'name' => $speaker->speakerFullName,
'jobTitle' => $speaker->speakerJobTitle,
'company' => $speaker->speakerCompany,
];
}
return [
'speakers' => $speakersList,
];
},
],
];
And the output:
{
"data": [
{
"speakers": [
{
"name": "John Doe",
"jobTitle": "Marketing",
"company": "Company 1",
},
...
I've tried the serialize options in the documentation, but none seemed to solve the issue.
Currently if I'd like to access the speakers within data I'd have to first access index[0] to be able to get to the speakers key.
Is there a way to get rid of this array level?

Store and retrieve nested JSON in DynamoDB with PHP SDK

I have created the following table in DynamoDB:
Field1: messageId / Type: String / Example value: 4873dd28-190a-4363-8299-403c535e160f
Field2: microtime / Type: Number / Example value: 14143960092414
Field3: data / Type: nested JSON-Array / Example value: {"foo":"bar","other":{"nested":1}}
I am performing the following request using PHP SDK for DynamoDB to create an entry
$raw = '{"foo":"bar","other":{"nested":1}}';
$result = $client->putItem(array(
'TableName' => 'requests2',
'Item' => array(
'messageId' => array('S' => '4873dd28-190a-4363-8299-403c535e160f'),
'microtime' => array('N' => microtime(true)*10000),
'data' => array('S' => $raw),
)
));
I want then to query the table and filter using variables within the JSON-array data field. Is my above solution to entering the data the right approach? The JSON-array gets stored as string, as to my understanding. Do we need another datatype? Basically, I can already query the table like below to retrieve messages that were added within the last minute:
$iterator = $client->getIterator('Query', array(
'TableName' => 'requests2',
'KeyConditions' => array(
'messageId' => array(
'AttributeValueList' => array(
array('S' => '4873dd28-190a-4363-8299-403c535e160f')
),
'ComparisonOperator' => 'EQ'
),
'microtime' => array(
'AttributeValueList' => array(
array('N' => strtotime("-1 minutes")*10000)
),
'ComparisonOperator' => 'GT'
)
)
));
foreach ($iterator as $item) {
echo $item['messageId']['S']." ";
}
But how can I modify my request to allow querying by ANY value within the data-field? For example, filter by only those who have [data][other][nested]=1
I've spent the past hours on this issue and I can't get it to work... I am very grateful for any tips, thanks in advance!
I know this was posted in 2014, but I was looking exactly for this answer and so I'd like to share the result in my search to anyone that will land on this question in the future.
Best practice is to store a JSON as a string, but use a Marshaler object to turn the JSON into something that DynamoDB can digest, and that you will be able to query too:
Using marshalJSON method you turn a JSON, as you can see described in this amazon link
For the ones that are looking for a quick example, I add here below the key parts of the procedure:
If you have a JSON like the following
{
"id": "5432c69300594",
"name": {
"first": "Jeremy",
"middle": "C",
"last": "Lindblom"
},
"age": 30,
"phone_numbers": [
{
"type": "mobile",
"number": "5555555555",
"preferred": true
},
{
"type": "home",
"number": "5555555556",
"preferred": false
}
]
}
stored in a string variable $json, you can simply do
use AwsDynamoDbDynamoDbClient;
use AwsDynamoDbMarshaler;
$client = DynamoDbClient::factory(/* your config */);
$marshaler = new Marshaler();
$client->putItem([
'TableName' => 'YourTable',
'Item' => $marshaler->marshalJson($json)
]);
I don't think AWS PHP SDK for DynamoDB has yet implemented the support for JSON based document storage. Their recent notification published on their blog on 8th October 2014, mentions about the support of this new feature only in Java, .NET, Ruby and JS SDK.

How to set OR condition in Phalcon PHP ORM?

I using Phalcon PHP as PHP MVC Framework with MongoDB.
I can find object according with some criteria:
$user = User::findFirst(array(array('username' => $login, 'email'=> $login)));
As you can note, this request will return me the record according logical AND operator between conditions. I need to form request that will return result according with OR operator between conditions.
The problem also is that I'm using MongoDB, so, as I can suppose, I can't write PHQL request manually.
Just a matter of mangling PHP arrays
$user = User::findFirst( array(
'$or' => array(
array( 'username' => $login),
array( 'email' => $login)
)
));
So not only do I show the answer but also how my totals non PHP mind solves this problem:
$result = '{ "$or": [ { "username": "login" }, { "email": "login" } ] }';
echo var_dump( json_decode( $result ) );
$test = array(
'$or' => array(
array( 'username' => 'login'), array( 'email' => 'login')
)
);
echo json_encode( $test ) ."\n"
So in just a few lines we converted and proved. So since you knew the JSON from either the manual page or reading another question on SO, just convert it. And it's one of the reasons I submit the valid JSON in responses here, is so that the logic can be translated into just about any language implementation.
You can pass column names as string in first param:
$user = User::findFirst('username = "'.$login.'" OR email = "'.$login.'"');
$result = '{ "$or": [ { "username": "login" }, { "email": "login" } ] }';
User::findFirst(array(json_decode($query,true)));
$result is the exact json which can be used to trigger queries in mongodb command line
json_decode with 2nd parameter true will output the array style format of JSON

Categories