Re-indexing an index in ElasticSearch to change the number of shards - indexing

I need to change the number of shards in my index. The index is quite big and i may have to change the configuration 10-15 times for testing purposes before i'm satisfied with the result. is there a tool offering out of the box this kind of functionality? or what's the easiest way of accomplishing this?

Both the Perl and Ruby clients directly support reindexing.
In Perl, you'd do:
my $source = $es->scrolled_search(
index => 'old_index',
search_type => 'scan',
scroll => '5m',
version => 1
);
$es->reindex(
source => $source,
dest_index => 'new_index'
);
Find more information in the post by Clinton Gormley.
In Ruby, you'd do:
Tire.index('old').reindex 'new', settings: { number_of_shards: 3 }
Find more information in the relevant Tire commit.

Related

redis - fetch all hashes by pattern/prefix

I have a hash pattern websocket:socket:*
$redis->hMSet('websocket:socket:1', ['block' => 9866]);
$redis->hMSet('websocket:socket:2', ['block' => 854]);
$redis->hMSet('websocket:socket:3', ['block' => 854]);
How can I fetch all hashes that matches pattern websocket:socket:* ??
Or what is the best way (performange wise) to keep track of a list of items?
Redis does not provide search-by-value out of the box. You'll have to implement some kind of indexing yourself.
Read more about indexing in Redis at Secondary indexing with Redis (or use RediSearch).

Laravel TNTsearch custom index creation and usage for large SQL database table

Here is my situation, context, and dilemma.
Situation
I'm fairly new to Laravel and still learning the ropes. I recently installed TNTSearch and Laravel Scout and was able to create a model index using the below config. I created the index using the console command php artisan tntsearch:import "App\Models\Product" and can fuzzy search successfully with App\Models\Product::search($keyword)->get().
config/scout.php
'tntsearch' => [
'storage' => storage_path() . '/index',
'fuzziness' => 'auto',
'fuzzy' => [
'prefix_length' => 2,
'max_expansions' => 50,
'distance' => 4,
],
'asYouType' => true
],
Context
I have an SQL database table with over 30k+ product records segmented per province (Canadian project), and instead of searching the whole index and later filter by market, I’d like to create one index per market and launch a search for a given market. I believe it will speed up the search and avoid returning results which will later be discarded! So basically having one product index file per province (i.e. products_on.index, products_qc.index, ...)
Dilemma/Issue
I am unable to find how to create such an index, have it update automatically and also how to use it. I scoured the Internet for tutorial/guidance and could only find scarce information I can hardly put together. I’d appreciate if someone could point me in the right direction or guide me on how to implement such a thing.
No answer is wrong, and any bits and pieces of information can help me greatly to “get up to speed.”
EDIT (July 30th, 2018):
I still haven't found the answer to my request but the more I search, the more I'm concluding search indexes are "tied" to a model, and it is not possible to have more than one index per model. So I would have to create one model extension per market from the original Listings model (Listings_QC, Listings_ON, ...). Then create an index per markets and search from those (Listings_QC::search(...)).
I'm not keen to create models based on data! Is this a good approach/practice?
RESOLVED !
My inexperience with Laravel search index in general lead me in the wrong direction!
I finally found a document explaining how to use searchBoolean() to search using "and". Modified my config as below to add the searchBoolean:
'tntsearch' => [
'storage' => storage_path() . '/index',
'fuzziness' => 'auto',
'fuzzy' => [
'prefix_length' => 2,
'max_expansions' => 50,
'distance' => 4,
],
'asYouType' => true,
'searchBoolean' => true
],
Then specify the market using the model's method toSearchableArray(), and add the market to any requested seach keyword.
For example, listing search with 'Alsace' for a QC market, I launch the search as
Listings::search('Alsace QC')->get().
Voilà! May help others hitting the same "wall"!

Elastalert : Cluster health notification

I don't know elastalert much.
I just wanted to know whether it is possible to get notification when cluster status is RED using elastalert.
Thank you
its possible. but you need to access it via the cluster health query.
sample:
input{
exec {
curl -u <username>:<password> <elasticsearch-ip:port>/_cluster/health
codec => rubydebug
type => cluster-health
}
}
output {
if "health" in [type] {
elasticsearch{
index => "cluster-health-%{+YYYY.MM.dd}"
hosts => ["elasticsearch-host:port"]
}
}
}
if you have filters that are not parsing it add a filter with if [type] == "cluster-health" section to filter and parse it as json.
this gives you basic details. though you may need to update the field mapping of status.. at least i am facing issue and you have readily availability. Now you can wuery as you normally would under elastalert.
Looks like they don't have this functionality out of the box yet. But there are some hacky ways to achieve it https://github.com/Yelp/elastalert/issues/903
They recommend to use Marvel instead.
No as far as I know.
Current Elastalert documentation state that the index field is mandatory in the rule .yaml file.
The current way elasticsearch cluster provide health status is via the healthapi so no index is available for querying.

Pull mass name list from database or in script?

I need to fill an input box with a first name and last name. The user will press "Randomize" and it will pull a random first and last name and fill the inputs.
My question is I'm not sure if I should put the names in tables (firstNames, lastNames) or just store them in a javascript file and pull straight from that.
I'm trying to follow the Single Responsibility Principle so I'm inclined to choose the former, but then I have two more models, two more seeders, two more tables, and probably a class to pull all that together. And then do I fill from a CSV file or just from a manually populated seeder? It seems like a lot of work and extra files for a 1-time use.
I know I'll get crap for this being an opinion based question but there is no one or where else to ask.
Also if you know of a place to ask these kind of questions that won't get me ripped apart I'd appreciate that.
I would suggest using the Faker PHP library. That way you wouldn't have to create extra tables, models, or have to worry about finding yourself fake data.
To install it in your project, simply add the dependency in your composer.json file. and run a composer update.
"require-dev": {
"fzaninotto/faker": "1.3.*#dev"
},
Then you can use it to create fake first and last names for you (in your controller most likely)
$faker = Faker\Factory::create();
$firstName = $faker->firstName;
$lastName = $faker->lastName;
Edit:
To add your own names you can either edit or override the name provider file located here.
I would like to suggest Fakerino a new fake generator PHP library, with a modern approach, easy to extend with custom data, custom fake data class, or pre-configured groups of data.
https://github.com/niklongstone/Fakerino
<?php
include ('../Fakerino/vendor/autoload.php');
use Fakerino\Fakerino;
$fakerino = Fakerino::create();
echo $fakerino->fake('Surname')->toJson(); //["Donovan"]
echo $fakerino->fake('NameFemale'); //Alice
//with configuration
$fakerino = Fakerino::create('./conf.php');
print_r($fakerino->fake('fake1')->toArray());
/*
Array(
[0] => Arthur
[1] => Doyle
)
*/
//conf.php
<?php
$conf['fake'] = array(
'fake1' => array('NameMale', 'Surname' => null),
'fake2' => array('NameFemale', 'Surname' => null)
);

RoR: how to tell which params in a form have changed

In a Rails application, I have a particular form with many fields for editing a resource. Since I also want to log what was changed for this particular resource, I need to know which params changed.
Currently in this form, I have duplicated every field in the form with hidden field tags, so in the controller every field is compared to the corresponding hidden field to determine if the value was changed. But it's a LOT of work in the view and in the controller.
Being relatively new to Rails, I'm finding all kinds of Rails "magic" as I go along, so I wonder: does the framework provide a way to do this for me? Or is this pretty much the only way?
ActiveModel has exactly what you're looking for, take a look at the examples in the docs...
http://api.rubyonrails.org/classes/ActiveModel/Dirty.html
person = Person.find_by_name('Uncle Bob')
person.changed? # => false
person.name = 'Bob'
person.changed? # => true
person.name_changed? # => true
person.name_was # => 'Uncle Bob'
person.name_change # => ['Uncle Bob', 'Bob']
person.name = 'Bill'
person.name_change # => ['Uncle Bob', 'Bill']
You can try Dirty attributes for this task.
#post.attributes = params[:post]
#post.changed # or changes if you want to see what values on which was changed
More on that you can find by this link: http://ar.rubyonrails.org/classes/ActiveRecord/Dirty.html
Also if you want to use versioning or auditing, try this gems (best ones are: paper_trail, acts_as_audited, vestal_versions):
https://www.ruby-toolbox.com/categories/Active_Record_Versioning
https://www.ruby-toolbox.com/categories/Active_Record_User_Stamping