How to format JSON object PHP - php

I am trying to create a POST to a REST API to create a new object. I cannot figure out how to properly format my JSON.
Here's the response from the GET of an existing object:
{
"name": "product 2 mem"
"type": "simple"
"categories": array:1 [▼
0 => {
"id": 75
}
]
"meta_data": array:1 [▼
"id": 3665
"key": "_yith_wcbm_product_meta"
"value": {
"id_badge": "2955"
}
}
]
}
Here is the POST I'm trying to create:
$data = [
'name' => 'product name',
'type' => 'simple',
'categories' => [
[
'id' => 75
],
'meta_data' => [
'_yith_wcbm_product_meta' => [
'id_badge' => '2955'
]
]
];

You got typo in you json data.
$response = '{
"id": 3665,
"key": "_yith_wcbm_product_meta",
"value": {
"id_badge": "2955"
}
}';
$array = json_decode($response,true);
$return = ['meta_data'=>['key'=>$array['key'],'value'=>$array['value']]];
echo json_encode($return);

I figured out how to format it:
'meta_data' => [
[
'key' => '_yith_wcbm_product_meta',
'value' => ['id_badge' => '2955']
]

Related

Transform nested collection in laravel

I have a nested collection that I want to transform, pulling some keys "up a level" and discarding some other keys.
Every item in the collection has an allergens property.
"allergens": [
{
"id": 2001,
"info": "Allergy advice",
"status": "does_contain",
"product_id": 71576,
"allergen_id": 1,
"allergen": {
"id": 1,
"name": "Celery"
}
},
{
"id": 2002,
"info": "Allergy advice",
"status": "may_contain",
"product_id": 71576,
"allergen_id": 11,
"allergen": {
"id": 11,
"name": "Peanuts"
}
}
],
I need to make each items allergens property, look like
"allergens": [
{
"id": 1,
"name": "Celery"
"status": "does_contain",
},
{
"id": 11,
"name": "Peanuts"
"status": "does_contain",
},
],
I've tried the following:
$collection = $collection->transform(function ($item, $key) {
$item->allergens = $item->allergens->map(function ($allergen) {
return [
'id' => $allergen->allergen->id,
'name' => $allergen->allergen->name,
'status' => $allergen->status,
];
});
return $item;
});
But it doesn't overwrite the allergens property
Since you're posting your collection as JSON, I reverse engineered what your actual collection would look like. Turns out, your transform() works fine as far as I can tell. Maybe that helps you to find differences between my and your collection which might lead you to your problem/solution:
$collection = collect([
(object)[
"allergens" => collect([
(object)[
"id" => 2001,
"info" => "Allergy advice",
"status" => "does_contain",
"product_id" => 71576,
"allergen_id" => 1,
"allergen" => (object)[
"id" => 1,
"name" => "Celery"
]
],
(object)[
"id" => 2002,
"info" => "Allergy advice",
"status" => "may_contain",
"product_id" => 71576,
"allergen_id" => 11,
"allergen" => (object)[
"id" => 11,
"name" => "Peanuts"
]
]
]),
]
]);
$collection = $collection->transform(function ($item, $key) {
$item->allergens = $item->allergens->map(function ($allergen) {
return [
'id' => $allergen->allergen->id,
'name' => $allergen->allergen->name,
'status' => $allergen->status,
];
});
return $item;
});
dd($collection);
Result:
Illuminate\Support\Collection {#1779 ▼
#items: array:1 [▼
0 => {#1791 ▼
+"allergens": Illuminate\Support\Collection {#1775 ▼
#items: array:2 [▼
0 => array:3 [▼
"id" => 1
"name" => "Celery"
"status" => "does_contain"
]
1 => array:3 [▼
"id" => 11
"name" => "Peanuts"
"status" => "may_contain"
]
]
}
}
]
}

append url for JSON array in laravel

I have a JSON field in my MySQL table column which has an JSON array with part of images URLs.
"images": [
{
"images": {
"original": "/storage/uploads/1.png",
"300": "/storage/uploads/300.1.png",
"600": "/storage/uploads/600.1.png",
"900": "/storage/uploads/900.1.png"
},
"thumb": "/storage/uploads/300.1.png"
},
{
"images": {
"original": "/storage/uploads/2.png",
"300": "/storage/uploads/300.2.png",
"600": "/storage/uploads/600.2.png",
"900": "/storage/uploads/900.2.png"
},
"thumb": "/storage/uploads/300.2.png"
},
{},
]
I want to get the array with appending a Base URL for each of the values of the array.
"images": [
{
"images": {
"original": "http://localhost:8000/storage/uploads/1.png",
"300": "http://localhost:8000/storage/uploads/300.1.png",
"600": "http://localhost:8000/storage/uploads/600.1.png",
"900": "http://localhost:8000/storage/uploads/900.1.png"
},
"thumb": "http://localhost:8000/storage/uploads/300.1.png"
},
{
"images": {
"original": "http://localhost:8000/storage/uploads/2.png",
"300": "http://localhost:8000/storage/uploads/300.2.png",
"600": "http://localhost:8000/storage/uploads/600.2.png",
"900": "http://localhost:8000/storage/uploads/900.2.png"
},
"thumb": "http://localhost:8000/storage/uploads/300.2.png"
},
{},
]
I have tried with Collections function like below code. But was not succeeded.
'images' => collect($item->images)->map(function ($image) {
return url($image);
})->all(),
For collections you would need to create a collection of the second images keyed array as well. collect() does not create a recursive collection.
So if you had the following array:
$item = [
"images" => [
[
"images" => [
"original" => "/storage/uploads/1.png",
"300" => "/storage/uploads/300.1.png",
"600" => "/storage/uploads/600.1.png",
"900" => "/storage/uploads/900.1.png"
],
"thumb" => "/storage/uploads/300.1.png",
], [
"images" => [
"original" => "/storage/uploads/2.png",
"300" => "/storage/uploads/300.2.png",
"600" => "/storage/uploads/600.2.png",
"900" => "/storage/uploads/900.2.png",
],
"thumb" => "/storage/uploads/300.2.png",
]
]
];
and you really wanted to use collection, then the following would work:
$item = collect($item['images'])->map(function ($item) {
$images = collect($item['images'])->map(function ($item) {
return url($item);
});
return [
"images" => $images->toArray(),
"thumb" => url($item['thumb']),
];
});
You can use nested foreach to solve this
$json = json_decode($item->images, true); // I'm using true to convert the json to array
$images = [];
foreach ($json as $index => $array) {
foreach ($array as $key => $value) {
if (is_array($value)) {
foreach ($value as $path_key => $path) {
$images[$index][$key][$path_key] = url($value[$path_key]);
}
} else {
$images[$index][$key] = url($value);
}
}
}
If you dd($images); you will get
array:2 [▼
0 => array:2 [▼
"images" => array:4 [▼
"original" => "http://localhost:8000/storage/uploads/1.png"
300 => "http://localhost:8000/storage/uploads/300.1.png"
600 => "http://localhost:8000/storage/uploads/600.1.png"
900 => "http://localhost:8000/storage/uploads/900.1.png"
]
"thumb" => "http://localhost:8000/storage/uploads/300.1.png"
]
1 => array:2 [▼
"images" => array:4 [▼
"original" => "http://localhost:8000/storage/uploads/2.png"
300 => "http://localhost:8000/storage/uploads/300.2.png"
600 => "http://localhost:8000/storage/uploads/600.2.png"
900 => "http://localhost:8000/storage/uploads/900.2.png"
]
"thumb" => "http://localhost:8000/storage/uploads/300.2.png"
]
]

Illegal Argument Exception when using Suggestors in Elasticsearch in PHP

I have tried implementing completion suggestor query in php as given here. My code is :
$params = [
"index" => $myIndex,
"body" => [
"try" => [
"text" => "ram",
"completion" => [ "value" => "suggest"]
]
]
];
$response = $client->suggest($params);
I have done indexing like this:
$params = [
"index" => $myIndex,
"body" => [
"settings"=> [
"analysis"=> [
"analyzer"=> [
"start_with_analyzer"=> [
"tokenizer"=> "my_edge_ngram",
"filter"=> [
"lowercase"
]
]
],
"tokenizer"=> [
"my_edge_ngram"=> [
"type"=> "edge_ngram",
"min_gram"=> 3,
"max_gram"=> 15
]
]
]
],
"mappings"=> [
"doc"=> [
"properties"=> [
"label"=> [
"type"=> "text",
"fields"=> [
"keyword"=> [
"type"=> "keyword"
],
"ngramed"=> [
"type"=> "text",
"analyzer"=> "start_with_analyzer"
]
]
]
]
]
]
]
];
$response = $client->indices()->create($params); // create an index
and I am getting the following error:
{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "[completion] unknown field [value], parser not found"
}
],
"type": "illegal_argument_exception",
"reason": "[completion] unknown field [value], parser not found"
},
"status": 400
}
I have tried changing value to value.keyword but it is showing same error. I am using elastic search 5.3.2 . How to resolve this error?
In the query you are using field 'value' inside the completion while it is not a field like this, that is the exact error is stating.
You can try the below solution:
$params = [
"index" => $myIndex,
"body" => [
"try" => [
"text" => "ram",
"completion" => [ "label" => "suggest"]
]
]
];
$response = $client->suggest($params);
Hope this will work.

How do I extract subdocument in laravel mongodb

Hello Good Developers,
I am using jenssegers/laravel-mongodb package to query my MongoDB from Laravel.
Here's Fiddle for my query: https://mongoplayground.net/p/qzbNN8Siy-3
I have following JSON
[{
"id": "GLOBAL_EDUCATION",
"general_name": "GLOBAL_EDUCATION",
"display_name": "GLOBAL_EDUCATION",
"profile_section_id": 0,
"translated": [
{
"con_lang": "US-EN",
"country_code": "US",
"language_code": "EN",
"text": "What is the highest level of education you have completed?",
"hint": null
},
{
"con_lang": "US-ES",
"country_code": "US",
"language_code": "ES",
"text": "\u00bfCu\u00e1l es su nivel de educaci\u00f3n?",
"hint": null
}...
{
....
}
]
I am trying to run following command
db.collection.find({ 'id': "GLOBAL_EDUCATION" },{_id:0, id:1, general_name:1, translated:{ $elemMatch: {con_lang: "US-EN"} }})
Expecting result like this
[
{
"general_name": "GLOBAL_EDUCATION",
"id": "GLOBAL_EDUCATION",
"translated": [
{
"con_lang": "US-EN",
"country_code": "US",
"hint": null,
"language_code": "EN",
"text": "What is the highest level of education you have completed?"
}
]
}
]
Everything is fine while query directly in MoDB but issue arise when I am trying this in Laravel.
I've tried every possible known function from MongoDB package. but Not able to do this.
here's my Array
$findArray = [
[
'id' => "GLOBAL_EDUCATION",
],
[
'_id' => 0,
'id' => 1,
'general_name' => 1,
'translated' => [
'$elemMatch' => ['con_lang' => "US-EN"]
],
]
];
$model = GlobalQuestions::raw()->find($findArray) //OR
$data = GlobalQuestions::raw(function($collection) use ($findArray){
return $collection->find($findArray);
});
What I am doing wrong here, is this kind of Find() not possible here and I've to do this by aggregation?
Since no-one answered this, I am posting the solution if someone is having the same issue.
Doing some more R&D on the same I was able to do this using where and Project as well by Aggregation Pipelines.
----- Using Where() and Project() ------
$projectArray = [
'_id' => 0,
'id' => 1,
'general_name' => 1,
'translated' => [
'$elemMatch' => ['con_lang' => "FR-FR"]
],
];
$data = GlobalQuestions::where('id', '=', 'GLOBAL_EDUCATION')
->project($projectArray)
->get();
--- Using Aggregation and $unwind ---
$data = GlobalQuestions::raw(function($collection) {
return $collection->aggregate([
[
'$match' => [
'id' => "GLOBAL_EDUCATION"
]
],
[
'$unwind' => '$translated',
],
[
'$match' => [
'translated.con_lang' => "US-EN"
]
],
[
'$project' => [
'_id'=> 0,
'id'=> 1,
'general_name' => 1,
'translated' => 1,
]
]
]);
})->first();

Elasticseach doesn't map all given fields [PHP]

I'm working with Elasticsearch-PHP client. I want to index my datas, but I have a problem with mapping. There is a problem: I create my data array, everything works fine, but when I add this array to my index body => my_data_array some datas show up, but not all of them. I don't know why. I just digged and try all of following steps but nothing changed.
I just attached my snippets.
This my controller file where I index datas:
{
$params = ['body' => []];
foreach($all_ads as $key => $ads){
$params['body'][] = [
'index' => [
'_index' => 'demo_data',
'_type' => 'demo',
'_id' => $ads->id
]
];
$params['body'][] = $ads->indexParams();
}
$responses = $client->bulk($params);
this is result json object:
"response": [
{
"id": 85345,
"old_id": "5088063",
"user_id": "2706",
"category_id": "15",
"type": "3",
"title": array[3],
"slug": "",
"sub_region_id": "8",
"condition": "1",
"username": "John Doe",
"price": "82000",
"price_type": "1",
"no_phone": "0",
"views": "29",
"hot": "0",
"vip": "0",
"price_measure": "0"
}
I have a datafield and it is not visible here.
Its data mapping structure
'data' => [
'type' => 'object',
'properties' => [
'key_id' => ['type' => 'integer'],
'value_id' => ['type' => 'integer'],
'key' => ['type' => 'keyword'],
'value' => ['type' => 'keyword']
]
]
How can I fix it?
I just check some question from here and github issue forum but nothing helps. Thanks!
You have to follow solution of the question. Its maybe helpful for you.
Elasticsearch mapping not working as expected
Ask Question

Categories