Use multiple Index search in multiple fields in Elasticsearch - php

This is my search query. Here I am trying to search inside two different fields of two different index but it is giving result from one index only
array:2 [
"index" => "items-123-*,asso-456-*"
"body" => array:1 [
"query" => array:1 [
"bool" => array:1 [
"should" => array:2 [
0 => array:1 [
"match" => array:1 [
"title" => "Civics"
]
]
1 => array:1 [
"match" => array:1 [
"type" => "matchOf"
]
]
]
]
]
]
]
I tried below way but not working
array:1 [
"body" => array:1 [
"query" => array:1 [
"bool" => array:1 [
"should" => array:2 [
0 => array:2 [
"term" => array:1 [
"_index" => "items-123-123"
]
"match_phrase" => array:1 [
"title" => "Civics"
]
]
1 => array:2 [
"term" => array:1 [
"_index" => "cfassociations-345-*"
]
"match_phrase" => array:1 [
"type" => "matchOf"
]
]
]
]
]
]
]

Use alias to search for multiple index. For index items-123-*
POST _aliases
{
"actions": [
{
"add": {
"index": "items-123-*",
"alias": "my-new-index"
}
}
]
}
And for index asso-456-*
POST _aliases
{
"actions": [
{
"add": {
"index": "asso-456-*",
"alias": "my-new-index"
}
}
]
}
Now you can search by using the alias name my-new-index.

Related

Laravel/PHP flatten multidimensional array

I'm wondering if someone can help with the following please? Currently I have this array:
array:1 [
"blocks" => array:3 [
0 => array:1 [
"component" => "TextColumns"
]
1 => array:2 [
0 => array:1 [
"component" => "TextColumns"
]
1 => array:1 [
"component" => "TextColumns"
]
]
2 => array:1 [
"component" => "TextColumns"
]
]
]
What I want to achieve is a final array of the below:
array:1 [
"blocks" => array:3 [
0 => array:1 [
"component" => "TextColumns"
]
1 => array:1 [
"component" => "TextColumns"
]
2 => array:1 [
"component" => "TextColumns"
]
3 => array:1 [
"component" => "TextColumns"
]
]
]
If I use array_flatten or laravels ->flatten() I do not get the desired results as it flattens it too much:
array:1 [
"blocks" => array:3 [
0 => array:1 [
"component" => "TextColumns"
]
1 => array:2 [
0 => "TextColumns"
1 => "TextColumns"
]
2 => array:1 [
"component" => "TextColumns"
]
]
]
EDIT: Here is some source code for reference. I have header, content and footer methods. Both header and footer will always return a single array. Content however will be a multidimensional array as there could be multiple content blocks i.e.
protected static function header(): array
{
return [
'component' => 'TextColumns',
];
}
protected static function content(): array
{
return [
[
'component' => 'TextColumns',
],
[
'component' => 'TextColumns',
],
];
}
Then this is all merged together in the following array. Hence I need the content blocks to be flattened so that the blocks array just contains a simple array
dd([
'blocks' => [
static::header(),
static::content(),
static::footer(),
],
]);
Any help would be appreciated!
Thanks

Transform Laravel collection and group by key

I would like to transform a collection of object in laravel, but I can't figure it out how. I want to group the record by the type column, and set the grouped record under an array key value.
public function transformData()
{
$data = collect();
$matches = [ 'race', 'ethnicity'];
$attributes = Attribute::withTrashed()
->whereIn('type', $matches)
->get()
->groupBy('type');
$data->put(
$type, // to be the group key(like race)
[
'values' => $attributes->toArray(), // to be all the value with type race
]
);
dd(collect($data));
}
Here is what I'm getting:
Illuminate\Support\Collection^ {#2368
#items: array:1 [
"values" => array:2 [
"ethnicity" => array:2 [
0 => array:2 [
"id" => 1
"type" => "ethnicity"
]
1 => array:2 [
"id" => 2
"type" => "ethnicity"
]
]
"race" => array:2 [
0 => array:2 [
"id" => 6
"type" => "race"
]
1 => array:2 [
"id" => 7
"type" => "race"
]
]
]
]
#escapeWhenCastingToString: false
}
BUT I would like to return this instead:
Illuminate\Support\Collection^ {#2368
#items: array:1 [
"ethnicity" => array:2 [
"value" => array:2 [
0 => array:2 [
"id" => 1
"type" => "ethnicity"
]
1 => array:2 [
"id" => 2
"type" => "ethnicity"
]
]
]
"race" => array:2 [
"value" =>
0 => array:2 [
"id" => 6
"type" => "race"
]
1 => array:2 [
"id" => 7
"type" => "race"
]
]
]
#escapeWhenCastingToString: false
}

Elasticsearch query is not working as expected

I have search query like this which is not working and giving me error
[bool] malformed query, expected [END_OBJECT] but found [FIELD_NAME]
array:2 [
"index" => "esdata"
"body" => array:1 [
"query" => array:2 [
"bool" => array:1 [
"should" => array:1 [
0 => array:1 [
"multi_match" => array:2 [
"query" => "History"
"fields" => array:1 [
0 => "*"
]
]
]
]
]
"terms" => array:1 [
"_id" => array:1 [
0 => "ae499e9d-8c9c-4d25-9f88-28f8fde64e10_*"
]
]
]
]
]
so I changed it to
array:2 [
"index" => "esdata"
"body" => array:1 [
"query" => array:1 [
"bool" => array:2 [
"should" => array:1 [
0 => array:1 [
"multi_match" => array:2 [
"query" => "History"
"fields" => array:1 [
0 => "*"
]
]
]
]
"must" => array:1 [
0 => array:1 [
"match" => array:1 [
"_id" => "ae499e9d-8c9c-4d25-9f88-28f8fde64e10_*"
]
]
]
]
]
]
]
but this is giving empty result
I am not familiar with the syntax of PHP, but the first query should be in the below format
{
"query": {
"bool": {
"should": [
{
"multimatch": {
"query": "History",
"fields": "*"
}
},
{
"terms": {
"_id": [
1,
2,
3
]
}
}
]
}
}
}
And the second query can be modified into:
{
"query": {
"bool": {
"should": [
{
"multimatch": {
"query": "History",
"fields": "*"
}
}
],
"must": {
"match": {
"_id": "ae499e9d-8c9c-4d25-9f88-28f8fde64e10_"
}
}
}
}
}
Note: match query works on analyzed text, whereas terms query will give you the result only when the search term exactly matches.

How to get value from unserialized data

I'm transforming my data into an array structure. Now I have the meta which already unserialized and I just need to take a specific value in meta.
Code
$item->meta;
$itm['attrs'] = #unserialize($item->meta);
$serial = #unserialize($item->meta);
$itm['product']['attrs'] = $itm['attrs'];
$itm['product']['serial'] = $serial['serial'];
Result
"product" => array:2 [
"attrs" => array:1 [
"serial" => array:1 [
0 => array:3 [
"id" => 848
"text" => "12345wf"
"trade_in" => 0
]
]
]
"serial" => array:1 [
0 => array:3 [
"id" => 848
"text" => "12345wf"
"trade_in" => 0
]
]
]
Expected Result
"product" => array:2 [
"attrs" => array:1 [
"serial" => array:1 [
0 => array:3 [
"id" => 848
"text" => "12345wf"
"trade_in" => 0
]
]
]
"serial" => "12345wf"
]
I'm not sure how to get the value and pass to the object.

How to merge two arrays?

After loop made and using following array I can create a new array.
$data[$val['gid']][$val['rid']][$val['aid']][$teno][$userid]= array();
This results in the array below:
array:1 [
"FS OTHER" => array:1 [
"FS OTHER" => array:1 [
"FS OTHER" => array:1 [
"FS OTHER" => array:1 [
"D111" => []
]
]
]
]
]
I also have another array:
array:41 [
0 => array:2 [
"sid" => "D111"
"desc1" => "BANGKOK"
]
1 => array:2 [
"sid" => "D111"
"desc1" => "NONTHABURI"
]
2 => array:2 [
"sid" => "D112"
"desc1" => "PATHUM THANI"
]
Now I need to merge this array based on the 'sid' to get the following result:
array:1 [
"FS OTHER" => array:1 [
"FS OTHER" => array:1 [
"FS OTHER" => array:1 [
"FS OTHER" => array:1 [
"BANGKOK" => []
"NONTHABURI"=> []
]
]
]
]
]
You can prepare another structure of the second array
$new = [];
foreach ($arr2 as $x) {
$new[$x['sid']][$x['desc1']] = [];
}
// [D111 => [ BANGKOK => [], NONTHABURI => [] ],..
and then just create the 1st one by:
$data[$val['gid']][$val['rid']][$val['aid']][$teno][$userid]= $new[$userid];

Categories