Firebase PHP Data Submission - arrayValue, mapValue - php

I am trying to push data to a firestore DB using PHP and the Google apis.
Inside the documentation and examples I have seen around the web, I am able to use mapValue and arrayValue when sending data.
The example I am using is as follows:-
[
"orderName" => [
"stringValue" => "Gbeila Aliu Wahab"
],
"orderLocationName" => [
"stringValue" => "Accra Mall Limited"
],
"orderTotalAmount" => [
"doubleValue" => 150.5
],
"orderDescription" => [
"stringValue" => "Lorem Ipsum is simply dummy text of the printing and typesetting industry"
],
"orderLocationGeoPoints" => [
"geoPointValue" => (object) [
"latitude" => 5.5557,
"longitude" => -0.1963
]
],
"orderStatus" => [
"stringValue" => "NotAssigned"
],
]
This works perfectly fine, but when I attempt to send an object or an array I get the following error returned to me:-
"message": "Invalid JSON payload received. Unknown name \"map_value\" at 'document.fields[0].value': Proto field is not repeating, cannot start list.",
when attempting to map the value using the following code:-
"orderName" => [
"mapValue" => ["Gbeila Aliu Wahab", 123]
]
// or
"orderName" => [
"arrayValue" => [
"first" => [
"stringValue" => "test"
],
"second" => [
"stringValue" => "test123"
]
]
]
I have tried many variations to try to get this to work.
How am I supposed to be using the mapValue and arrayValue I can see a lot of mentions regarding the value option but I cannot see any examples on how to use the.
Any help would be greatly appreciated.

Payload to your array or map you're generating is incorrect as per the documentation. You need to wrap your actual data (to store) under values key, your final array should be:
["orderName" => ["arrayValue" => ["values" => [["stringValue" => "test"], ["stringValue" => "test123"]]]]]
Similarly your mapValue should be
["orderName" => ["mapValue" => ["fields" => ["field1" => ["stringValue" => "Gbeila Aliu Wahab"]]]]]
Also, you can play with other data mapper via this package.

Related

Symfony set request parameters in array format

I'm trying to set up my own request which I could send to a method for testing purposes, but I can't seem to find how to format it.
Right now I'm trying to pull array out of the request
$data = $request->request->get('itemData');
It should look like this once I get it:
[
'basic' => [
'type' => 1
'country => 1
],
'information' => [
'wadding' => 1
]
]
I have written it like this:
$request->request->set("itemData[basic][type]", 2);
$request->request->set("itemData[information][wadding]", 0);
But I get null since the key is not itemData but for example itemData[basic][type]
How do I format it in the set command so the request parameters are sent in array form?
Figured it out
$request->request->set("itemData",
[
'basic' => ['type' => 2, 'country' => 1],
'information' => ['wadding' => 0]
]
);

How to write a PHP script that searches a PHP file for specific information?

Disclaimer: This is my first foray into PHP and scripting in general - all of my development experience is in iOS (Swift and Objective-C). I've started doing a tutorial.
We have a large .php file, let's call it objects.php, with a number of static variables.
The structure looks something like this:
'ObjectDictionaryTom' => [
A_Class::NAME => "Tom"
]
'ObjectDictionaryDick' => [
A_Class::NAME => "Dick"
]
'ObjectDictionaryHarry' => [
A_Class::NAME => "Harry"
]
'ObjectDictionaryAlsoTom' => [
A_Class::NAME => "Tom"
]
The structure isn't consistent; Sometimes, it even looks like this:
`Objects` => [
'ObjectDictionaryTom' => [
A_Class::NAME => "Tom"
],
'ObjectDictionaryDick' => [
A_Class::NAME => "Dick"
],
'ObjectDictionaryHarry' => [
A_Class::NAME => "Harry"
],
'ObjectDictionaryAlsoTom' => [
A_Class::NAME => "Tom"
]
]
How can I read through this file and get all objects that belong to "Tom"? Maybe gather them in a CSV?
I'm happy to edit or explain further as needed!
How about something like this:
'(.*?)'\s*=>\s*\[[\n\r\s]*\s*(.*?)\s*=>\s*"(.*?)"
As you can see here at regex101.com
You can see in the sidebar provided which capturing groups store which values - in particular, the ones you want are in capturing groups 1 (the first set of parentheses).
To access them, just get the values of capturing group 1 from the result.

(Elasticsearch) Convert Unix formatted data into timestamp (without changing the mappings)

We're executing an Elasticsearch query like this using PHP API:
$params = [
//please ignore the variables below,
//we made it in dynamic parameter-based in our function,
//that's why they're variables
'index' => $ourIndex,
'type' => $ourType,
'from' => $from,
'size' => $page_size,
'body' => [
"query" => [
'bool' => [
'must' => [
[
"query_string" => [
"default_field" => $content,
"query" => "$keywords"
]
],
[
"range" => [
"#timestamp" => [
"from" => $parseParams['pub_date_start'],
"to" => $parseParams['pub_date_end'],
'format' => "yy-MMM-dd'T'HH:mm:ss.SSS'Z'",
]
]
]
]
]
]
]
];
The query above works with our #timestamp field because its type is on date
"#timestamp" : {
"type" : "date"
}
And a sample value is like this:
"#timestamp" : "2019-06-17T16:53:55.778Z"
However, we want to target our pub_date field in our index, and in its mapping, the field has a type of long
"pub_date" : {
"type" : "long"
},
so it has this kind of values when we're displaying the documents:
"pub_date" : 1510358400
When we changed the query above to target instead of #timestamp to pub_date, it now displays an error like this:
Tried Solutions
I tried to add an additional format epoch_millis in the format property:
[
"range" => [
"pub_date" => [
"from" => $parseParams['pub_date_start'],
"to" => $parseParams['pub_date_end'],
'format' => "yyyy-MM-dd||yy-MMM-dd'T'HH:mm:ss.SSS'Z'||epoch_millis",
]
]
]
But still fails
Main Question
I feel that the Unix formatted values cant be recognized by the range query of Elasticsearch so that's why the query fails. Is there a work-around for this without changing the MAPPINGS of the index?
Because the other possible solutions suggested to change the mapping, but we already have around 25 million documents in the index, so we thought formatting it in PHP would be a nicer approach
Since the field is of type long and stores the unix timestamp, simply convert the date in $parseParams['pub_date_start'] and $parseParams['pub_date_end'] to unix timestamp using strtotime. Update the range query as below:
"range" => [
"pub_date" => [
"from" => strtotime($parseParams['pub_date_start']),
"to" => strtotime($parseParams['pub_date_end']),
]
]

How can I fetch results from elastic search from one column with different values at the same time?

I am using REST API using PHP for fetching data from Elastic search with following code
$params = [
'index' => $search_index,
'type' => $search_type,
'from' => $_POST["from"],
'size' => $_POST["fetch"],
'body' => [
'query' => [
'bool' => [
'must' => [
[ 'match' => [ 'is_validated' => false ] ],
[ 'query_string' => [ 'query' => $search_str, 'default_operator' => 'OR' ] ]
]
]
]
]
];
Now, this is working perfectly and giving me my desired results.
The data that is returned from ES, has one column "result_source" and it has predefined values like CNN, BBC or YouTube etc.
What I need is, I want to filter results on "result_source" column in a way that, I can only fetch the results with the option I want. Like I want results that have "result_source" value only "YouTube" or only "BBC & CNN" or only "CNN or YouTube" etc.
I have already tried "Should" option, but it also returns the data with other values that I don't need. Not sure how to skip those values of "result_source" column in fetching results from ES.
Any help on this will be appreciated.
Thanks
Solved!!
I am replying to my own question, because I found a solution for it. May be it can help someone else in future.
If anyone is looking for a solution of searching within the field / column of Elastic search, here is what can be done.
[ 'query_string' => [ 'query' => $search_str.'(result_source:CNN OR result_source:BBC)', 'default_operator' => 'OR' ] ]
"result_source" is actually the field / column name of ES on which filter is applied to return results that have result_source=BBC or result_source=CNN.
This actually solved my issue.

Combine two queries in one request

I want to execute multiple queries on elasticsearch server with one request. Specifically I have the following query (is on elastcisearch-php-client)
$params = [
"index" => "bookydate",
"type" => "vendor_service",
"body" => [
"query" => [
"bool" => [
"must" => [
"term" => [
"sys_service_id" => $request->input("sys_service_id")
]
],
"should" => [
"geo_shape" => [
"served_location" => [
"shape" => [
"type" => "point",
"coordinates" => [
"{$request->input('loc_lon')}",
"{$request->input('loc_lat')}"]
]
]
]
]
]
]
]
];
What I want to do is the fetch also all the documents that have the "hole_country" field to true.
What I have tried already is to make another request to Elasticsearch server and with array_merge combine the two results, but did not work because of PHP restrictions on arrays with multiple same keys.
UPDATE
Elastcisearch supports a feature called Multisearch that is exactly what im looking for. The problem is that php-client does not support multisearch so I have to use Guzzle in order to send the requests.
Guzzle docs does not have a full info about how to construct a correct request body. Any info is welcome
Already i have the following body but elastcisearch is returing bad request error
$body = [
["index"=>"bookydate"],
["query"=>["bool"=> ["must"=>[["term"=>["sys_service_id"=>"1"]],["geo_shape"=>["served_location"=>["shape"=>["type"=>"circle","coordinates"=>[25,3],"radius"=>"90km"]]]]]]]],
["index"=>"bookydate"],
["query"=>["bool"=>["must"=>["term"=>["hole_country"=>true]]]]]
];
You can use the multisearch API of Elasticsearch. This is more or less appending all your queries as JSON format in a single POST request. I hope the PHP client supports this, otherwise you might have to manually do the POST request.
Multi-search API
Although it's not documented the Multi Search API is supported by the elasticsearch php client.
Instead of search call msearch, and group your queries like this:
$params = [
'body' => [
["index" => "bookydate", "type" => "vendor_service"],
["query" => [
"bool" => [
"must" => [
"term" => [
"sys_service_id" => $request - > input("sys_service_id")
]
],
"should" => [
"geo_shape" => [
"served_location" => [
"shape" => [
"type" => "point",
"coordinates" => [
"{$request->input('loc_lon')}",
"{$request->input('loc_lat')}"
]
]
]
]
]
]
]]
];
So using your updated syntax is correct. You must just call msearch.

Categories