I need to search multiple ids in the Elastic search. same like IN in SQL.
When I write static multiple IDs, it works but when I make IDs array and then implode to make comma-separated IDs for ES. It does not work.
Implode query:
$ids = array();
foreach ($this->session->userdata('cart') as $key => $value) {
$ids[] = trim($key);
}
$params = [
'index' => ES_INDEX_PD,
'body' => [
'query' => [
'constant_score' => [
'filter' => [
'terms' => [
'id' => [implode(",", $ids)]
]
],
]
]
]
];
$products = $this->elasticsearch->client->search($params);
This is from imploding result... Does not work
Array ( [index] => example-prod [body] => Array ( [query] => Array ( [constant_score] => Array ( [filter] => Array ( [terms] => Array ( [id] => Array ( [0] => 10241308,10928958 ) ) ) ) ) ) )
This is static IDs passed to query. This works
Array ( [index] => example-prod [body] => Array ( [query] => Array ( [constant_score] => Array ( [filter] => Array ( [terms] => Array ( [id] => Array ( [0] => 10241308 [1] => 10928958 ) ) ) ) ) ) )
No need to use extra implode() with , here when you pass ids. I had the same issue couple of months back.Just pass the array of ids like this to your terms query and it'll work perfectly.
$ids = array();
foreach ($this->session->userdata('cart') as $key => $value) {
$ids[] = trim($key);
}
$params = [
'index' => ES_INDEX_PD,
'body' => [
'query' => [
'constant_score' => [
'filter' => [
'terms' => [
'id' => $ids
]
],
]
]
]
];
$products = $this->elasticsearch->client->search($params);
Related
I would like some advice on how to deal with this use case:
I have the following multidimentional test array with unknow depth:
$entries =
[
[
'id' => 'Foo',
'parent' => 'root',
'logic_rules' => []
],
[
'id' => 'Bar',
'parent' => 'root',
'logic_rules' => [],
'children' => [
[
'id' => 'Foobar',
'parent' => 'Bar',
'logic_rules' => [],
'children' => [
[
'id' => 'Foobar2',
'parent' => 'Foobar',
'logic_rules' => [],
'children' => [
[
'id' => 'Foobar3',
'parent' => 'Foobar2',
'logic_rules' => []
]
]
]
]
]
]
]
];
And I try to traverse the array to execute some logic (excluded from the example), with this recursive function:
function traverse(array $entries, array &$result = [])
{
foreach ($entries as $k => $value) {
// If `logic_rules` exists proceed executing the logic
// and store the result in the same `parent -> id` position
if (array_key_exists('logic_rules', $value)) {
$result[$value['parent']][$value['id']]['logic_rules'] = time(); // some logic
}
// Re-loop if is parent
if (array_key_exists('children', $value)) {
traverse($value['children'], $result);
}
}
return $result;
}
The output of traverse($entries) is:
Array
(
[root] => Array
(
[Foo] => Array
(
[logic_rules] => 1603091236
)
[Bar] => Array
(
[logic_rules] => 1603091236
)
)
[Bar] => Array
(
[Foobar] => Array
(
[logic_rules] => 1603091236
)
)
[Foobar] => Array
(
[Foobar2] => Array
(
[logic_rules] => 1603091236
)
)
[Foobar2] => Array
(
[Foobar3] => Array
(
[logic_rules] => 1603091236
)
)
)
But I expect this:
Array
(
[root] => Array
(
[Foo] => Array
(
[logic_rules] => 1603091236
)
[Bar] => Array
(
[logic_rules] => 1603091236
[Foobar] => Array
(
[logic_rules] => 1603091236
[Foobar2] => Array
(
[logic_rules] => 1603091236
[Foobar3] => Array
(
[logic_rules] => 1603091236
)
)
)
)
)
)
Seems like it's skipping its ancestors. Any advice on this?
The solution is to refer to the results parent so the following depth will push to it.
Look at this line:
traverse($value['children'], $result[$value['parent']]);
This code will work for you:
function traverse (array $entries, array &$result = []) {
foreach ($entries as $value) {
// add your logical stuff here
$result[$value['parent']][$value['id']] = array(
'logical_rules' => time()
);
if (array_key_exists('children', $value)) {
traverse($value['children'], $result[$value['parent']]);
}
}
return $result;
}
I have 2 arrays:
first array of total transactions (haystack):
[0] => Array (
[transaction_id] => 62369600431
[invoice_number] => 37161
)
[1] => Array (
[transaction_id] => 62369595048
[invoice_number] => 37346
)
[2] => Array (
[transaction_id] => 62369537530
[invoice_number] => 38064
)
Second array of select orders (needle):
[0] => Array (
[invoice_number] => 37161
)
[1] => Array (
[invoice_number] => 37346
)
My goal is to create a third array that finds all transaction_id from the first array that have a match of order_id from the second.
I have tried array_merge and array_intersect both unsuccessfully (because I don't fully understand how to use them obviously.)
You might use array_filter and get all the invoice_numbers to check for using example array_column.
Then in the filter, check if the number occurs in the invoice_numbers using in_array.
$array1 = [
[
"transaction_id" => 62369600431,
"invoice_number" => 37161
],
[
"transaction_id" => 62369595048,
"invoice_number" => 37346
],
[
"transaction_id" => 62369600431,
"invoice_number" => 38064
]
];
$array2 = [
[
"invoice_number" => 37161
],
[
"invoice_number" => 37346
]
];
$invoiceNumbers = array_column($array2, "invoice_number");
$result = array_filter($array1, function($x) use ($invoiceNumbers) {
return in_array($x["invoice_number"], $invoiceNumbers);
});
print_r($result);
Output
Array
(
[0] => Array
(
[transaction_id] => 62369600431
[invoice_number] => 37161
)
[1] => Array
(
[transaction_id] => 62369595048
[invoice_number] => 37346
)
)
Php demo
I have to fetch the record from the form of an array. following is an array result.
Array(
[price] => Array
(
[0] => 210
)
[code] => Array
(
[0] => SER-1001
)
)
Array
(
[price] => Array
(
[1] => 80
)
[code] => Array
(
[1] => XYZ-121
)
)
Now I am confused, how to update that records in product table where a code is e.g. SER-1001 in the database then the price should be updated 210.
Same way as I do rest of matching code records.
foreach ($arr as $key => $value) {
$data = array(
'price'=> $value['price'];
);
$this->db->where('code', $value['code']);
$this->db->update(‘database-table-name’,$data);
}
try this, here you are looping through the array and updating the data one by one.
$array = [
[
'price' => [ '0' => 210],
'code' =>['0' => 'SER-1001']
],
[
'price' => ['1' => 80],
'code' =>['1' => 'XYZ-121']
]
];
With reference to the above output array. You can write the code something like this.
$counter = 0;
foreach($array as $data)
{
if(isset($data['code'][$counter]))
{
$code = $data['code'][$counter];
$data = [
'price' => $data['price'][$counter];
];
$this->db->where($column, $code);
$this->db->update('database-table-name',$data);
}
$counter++;
}
I am trying to search this array by the value of ['field'] and then return the value of ['value'] associated with that field in the array.
For example, I want to say "Tell me the value associated with theThirdField".
I've tried many, many permutations of something like the following:
$myVariable = $Array['result']['totalrows'][0]['rownum'][0]['field'];
To further clarify, I will never know which order / sub-array my search field is located in, I only know the string value associated with ['field'].
How would I accomplish this?
Array
(
[result] => Array
(
[totalrows] => 1
[rows] => Array
(
[0] => Array
(
[rownum] => 1
[values] => Array
(
[0] => Array
(
[field] => testMeOnce
[value] => 436586498
)
[1] => Array
(
[field] => testMeTwice
[value] => 327698034
)
[2] => Array
(
[field] => theThirdField
[value] => 108760374
)
[3] => Array
(
[field] => theFourthField
[value] => 2458505
)
[4] => Array
(
[field] => fifthField
[value] => -0.0201
)
)
)
)
)
)
Did you expect something like that?
$needle = 'theThirdField'; // searched field name
$valuesArray = $Array['result']['rows'][0]['values']; //now you have clearer array
array_walk($valuesArray, function($element, $key) use ($needle) {
if ($element['field'] == $needle) {
echo $element['value'];
}
});
I would do something like this, assuming you want to search only in the $myVariable dimension :
$myVariable = $Array['result']['rows'][0]['values'];
foreach ($myVariable as $key => $value) {
if( $value['field'] === 'theThirdField' ) {
echo $value['value'];
break;
}
}
when I ran your code, I got some syntax errors. I have changed your Array to this (changed syntax only):
$a = Array
(
'result' =>
[
'totalrows' => 1,
'rows' =>
[
0 =>
[
'rownum' => 1,
'values' =>
[
0 =>
[
'field' => 'testMeOnce',
'value' => 436586498
],
1 =>
[
'field' => 'testMeTwice',
'value' => 327698034
],
2 =>
[
'field' => 'theThirdField',
'value' => 108760374
],
3 =>
[
'field' => 'theFourthField',
'value' => 2458505
],
4 =>
[
'field' => 'fifthField',
'value' => -0.0201
]
]
]
]
]
);
now you can get the value like this:
print($a['result']['rows'][0]['values'][2]['value']); // --> 108760374
I hope that this is what you are looking for!
Thanks everyone. I used a mix of your suggestions and ended up doing the following:
$valuesArray = $Array['result']['rows'][0]['values'];
foreach ($valuesArray as $value) {
$fieldName = $value['field'];
$$fieldName = $value['value'];
}
Since I know the names of all the fields I want, but not the order, this allowed me to capture all of the values of each field with the name of the field becoming the variable name.
So as you can see below I have an array that I get from an ajax request.. Now is my question how can I use the [name] as an array? The arrays below are two different arrays
Changing the arrays below is done in PHP
So this:
(
[name] => template[options][4892][is_delete]
[value] => 1
)
(
[name] => template[options][4892][name]
[value] => just_a_name
)
Into this
(
[template] => (
[options] => (
[4892] => (
name => just_a_name,
is_delete => 1
)
)
)
)
Edited: changed value to is_delete
Edit2: changed some things to make it more clear
Hope this is clear enough
$data = [
[
'name' => 'template[options][4892][is_delete]',
'value' => 1
],
[
'name' => 'template[options][4892][name]',
'value' => 'name'
]
];
$parsedData = [];
foreach ($data as $item) {
parse_str($item['name'] . '=' . $item['value'], $out);
$parsedData = array_replace_recursive($parsedData, $out);
}
print_r($parsedData);
result:
Array(
[template] => Array(
[options] => Array(
[4892] => Array(
[is_delete] => 1
[name] => name
)
)
)
)