Using Maatwebsite/Laravel-Excel numbers have decimals - laravel-5

I am using Maatwebsite/Laravel-Excel to import a csv. The csv file looks like:
id;parent;name
1;0;Home
2;0;Contact
3;2;Thank you
4;0;Blog
5;4;Article 1
6;4;Article 2
The code is:
$rows = Excel::load('file.csv')->get();
$rows->each(function($row) {
dd($row->toArray());
});
The output is like:
array:3 [
"id" => 1.0
"parent" => 0.0
"name" => "Home"
]
So the regular numbers have a decimal added to it. How do I make it a regular integer without decimals? I know how to do it afterwards, but is it possible at load also?

Related

How to force Elastic to keep more decimals from a float

I have some coordinates that I pass to Elasticsearch from Logstash, but Elastic keeps only 3 decimals, so coordinate wise, I completely lose the location.
When I send the data from Logstash, I can see it got the right value:
{
"nasistencias" => 1,
"tiempo_demora" => "15",
"path" => "/home/elk/data/visits.csv",
"menor" => "2",
"message" => "5,15,Parets del Vallès,76,0,8150,41.565505,2.234999575,LARINGITIS AGUDA,11/3/17 4:20,1,38,1,2,POINT(2.2349995750000695 41.565505000000044)",
"id_poblacion" => 76,
"#timestamp" => 2017-03-11T04:20:00.000Z,
"poblacion" => "Parets del Vallès",
"edad_valor" => 0,
"patologia" => "LARINGITIS AGUDA",
"host" => "elk",
"#version" => "1",
"Geopoint_corregido" => "POINT(2.2349995750000695 41.565505000000044)",
"id_tipo" => 1,
"estado" => "5",
"cp" => 8150,
"location" => {
"lon" => 2.234999575, <- HERE
"lat" => 41.565505 <- AND HERE
},
"id_personal" => 38,
"Fecha" => "11/3/17 4:20"
}
But then, I get it on Kibana as follows:
I do the conversion as follows:
mutate {
convert => { "longitud_corregida" => "float" }
convert => { "latitude_corregida" => "float" }
}
mutate {
rename => {
"longitud_corregida" => "[location][lon]"
"latitude_corregida" => "[location][lat]"
}
}
How can I keep all the decimals? With geolocation, one decimal can return the wrong city.
Another question (related)
I add the data to the csv document as follows:
# echo "5,15,Parets del Vallès,76,0,8150,"41.565505","2.234999575",LARINGITIS AGUDA,11/3/17 4:20,1,38,1,2,POINT(2.2349995750000695 41.565505000000044)" >> data/visits.csv
But in the original document, instead of dots there are comas for the coordinates. like this:
# echo "5,15,Parets del Vallès,76,0,8150,"41,565505","2,234999575",LARINGITIS AGUDA,11/3/17 4:20,1,38,1,2,POINT(2.2349995750000695 41.565505000000044)" >> data/visits.csv
But the problem was that it was getting the coma as field separator, and all the data was being sent to Elasticsearch wrong. Like here:
Here, the latitude was 41,565505, but that coma made it understand 41 as latitude, and 565505 as longitude. I changed the coma by dot, and am not sure if float understands comas and dots, or just comas. My question is, did I do wrong changing the coma by dot? Is there a better way to correct this?
Create a GEO-Point mapping for the lat/lon fields. This will lead to a more precise and internally optimized storage in ES and allow you more sophisticated GEO-Queries.
Please keep in mind, that you'll need to reindex the data as mapping changes are not possible afterwards (if there are already docs present having the fields to change)
Zero downtime approach:
Create a new index with a optimized mapping (derive it from the current, and make your changes manually)
Reindex the data (at least some docs for verification)
Empty the new index again
Change the logstash destination to the new index (consider using aliases)
Reindex the old data into the new index

PHP array_map() always change my first index value to zero value

I have a controller in Laravel
This is my collection
$milestones = $this->getmilestones();
dump($milestones);
and the value is
array:3 [▼
0 => "["109"
1 => "110"
2 => "111"]"
]
And I tried this code based on the answer here.
So, I have code like this
array_unshift($milestones, $milestones[0]);
unset($milestones[0]);
dump($milestones);
and the value is (index was changed)
array:3 [▼
1 => "["109"
2 => "110"
3 => "111"]"
]
So, after unshifting the collections, I tried to use array_map to convert array of strings to array of integers.
$milestones = array_map('intval', $milestones);
dump($milestones);
But, I still got the same value. The first index returns 0 like this
array:3 [▼
1 => 0
2 => 110
3 => 111
]
What should I do?
Try this one
array_splice($milestone, 0, 1);
dump($milestone);
Ah, finally I got the results that I wanted. I try to remove square brackets and double quote. Because milestones is collection. So my code is
$milestones = str_replace(array('[', ']', '"'),'',$milestones);
Thank you all for your help
Use array_values this should re-index your array the way you need it:
$milestones = array_values($milestones);
If $milestones is a collection:
$milestones = $milestones->values();
The method values() will call array_values on your items defined in your collection instance.
Source: http://php.net/manual/en/function.array-values.php

How to search for an exact sub-string in aws cloudsearch?

When I search for 'bcde' I would like to get all of the following matches:
'abcde'
'bcdef'
'abcdef'
What is the way to achieve this result in AWS cloudsearch (preferably with a simple query parser)? Prefix will not give me the first result. Is there any other way?
After a few attempts at examples and without success. I decided as follows:
I created a text-array field and stored it part by part of the string from back to front and it worked.
example: my string is "abcde" and i search bcde. this would not work
but in my field text-field will be the following strings:
e, de, cde, bcde, abcde. So you will find "abcde" because he will find the term in the text-array field.
Oh man, but if i search bcd this term not in text-array field.
All right but the string "bcde" starts with "bcd" so IT WORKS! =)
my php file to insert looks like this:
$term = "abcde";
$arrStr = str_split($term);
$arrTerms = [];
$aux = 1;
foreach($arrStr as $str){
$arrTerms[] = substr($term,($aux * -1));
$aux++;
}
$data = [
'type' => 'add',
'id'=> [your_id],
'fields' => [
'id'=> [your_id],
'field-text' => $term
'field-text-array' => $arrTerms
],
];
If your index field is of type "text", A simple structured query will return all the matches which include your query string.
Example
Query : ( and part_part_number:'009' )
Result:
1 _score 10.379914
part_part_number 009
2 _score 10.379914
part_part_number A-009-DY
3 _score 10.379914
part_part_number BY-009

How to get an array of 2-tuples from Laravel query builder?

Basically, I want to do this:
$locals['companies'] = Company::orderBy('name')->get(['id','name'])->map(function($c) { return [$c->id, $c->name]; })->toArray();
But without such a verbose map function. Isn't there a get-like method that will return flat numeric arrays instead of objects?
To be clear, the output should look like this:
array:4 [
0 => array:2 [
0 => 4
1 => "My Company"
]
1 => array:2 [
0 => 14
1 => "Example Company"
]
2 => array:2 [
0 => 13
1 => "Best Company"
]
3 => array:2 [
0 => 12
1 => "Super Co"
]
]
This is what I mean by 2-tuples: two-element numeric arrays. I know they don't exist in PHP, but the concept is the same; each entry has a fixed length.
There is no function out of the box to do this, but Laravel's Collection is Macroable, so you can add your own function to it to do this.
For example, somewhere in your code (like the boot() method of your AppServiceProvider), you can add a new method to the Collection:
// add toIndexedArray method to collections
\Illuminate\Support\Collection::macro('toIndexedArray', function() {
return array_map('array_values', $this->toArray());
});
Now you can use this new method like any other normal Collection method, so your final code would be:
$locals['companies'] = Company::orderBy('name')->get(['id','name'])->toIndexedArray();
If this is something you need a lot, you can change the PDO fetch mode in config/database.php to PDO::FETCH_NUM. I'm assuming it's possible to change it on-the-fly as well, but the code probably won't look that great. I don't think there's a Laravel command to change it for a single query, I'm afraid.
Otherwise, since the array is multidimensional, I'm afraid you do need to map over them somehow, and Laravel collections don't work nicely with e.g. ->map('array_values') which would have been a lot cleaner.
You could wrap it in array_map('array_values', $array) but that seems silly.
At least you could make it a little shorter if you change ->map() to ->transform() - then you don't need to tack on the ->toArray() at the end.
Use pluck():
$locals['companies'] = Company::orderBy('name')->pluck('id', 'name')->toArray();
If you need a list for Form::select this will work:
$locals['companies'] = Company::orderBy('name')->pluck('name', 'id');
You can omit the map function and just do:
$locals['companies'] = Company::orderBy('name')->get(['id','name'])->toArray();

Laravel - Access Config value using a wildcard?

Let's say that I have a config file called templates.php
It stores a list of types and items.
Now, I know that in order to obtain a specific row I could just do Config::get("list.type1.item1");
<?php
return [
'list' => [
'type1' => [
'item1' => [
//
],
'item2' => [
//
],
'item3' => [
//
],
],
]
];
But the thing is that 'type1' is dynamic, so I need a way to get all elements that matches item name.
Something like this (wildcards are not supported, so it doesn't work)
Config::get("list.*.item1");
What's the fastest (okay, that doesn't actually matter, I just want to know if it can be done at all) possible way to achieve this?
You only need to put your dynamic type on a variable let's says:
$type = 'type1';
config('services.' . $type . '.item1');

Resources