In a previous post I described how simple integrating elasticsearch is with Rails for beginners. You could’ve been happy with the fact that you now have implemented full text search, but that too basic set up probably doesn’t work that much better than adding a column to your model, throwing in all text in it and running a LIKE query (although elasticsearch does try to rearrange the results a bit).
In this post I will learn you two things that makes elasticsearch worth it.
Analyzers add some fuzziness to your searches. First, make sure your analyzer is in the right language, this will improve your results. You add the following bit to your model (I typically place it just below where the scopes and validation are defined).
settings index: { number_of_shards: 1 } do
mappings do
indexes :title, analyzer: 'dutch', index_options: 'offsets'
indexes :body, analyzer: 'dutch', index_options: 'offsets'
end
end
If you’d already indexed your articles you should reindex them first:
Article.__elasticsearch__.refresh_index!
Article.import
(this is actually not recommended for production updates, but it works for now when testing)
Then, change from the default ‘match’ filter to a fuzzy search:
Article.search( query: {
fuzzy: {
_all: "elasticseerch"
}
})
And you’ll probably find the article titled ‘elasticsearch’ (if present)
Note: in the previous article I directly mapped the results to ActiveRecord objects, you get these by calling the .records
method after the search.
Another important feature of elastic search is filtering. You may want to filter only on articles within the category ‘search’. You can filter the articles in the following way:
Article.search(
query: {
filtered: {
query: {
match_all: {}
},
filter: {
term: {
"category.title"=>"search"
}
}
}
}
)
Tip: Do know that the regular strings get some processing, hence even when your category is named “Search”, the default analyzer has lowered the case down to “search”. You can turn this off if you want one on one matching…
On most websites you’ll probably want to offer both filtering and searching. We can simply combine the two above queries:
Article.search(
query: {
filtered: {
query: {
fuzzy: {
_all: "elasticseerch"
}
},
filter: {
term: {
"category.title"=>"search"
}
}
}
}
)
If you want to increase the number of results returned, increase the default limit:
Article.search(
query: {
filtered: {
query: {
fuzzy: {
_all: "elasticseerch"
}
},
filter: {
term: {
"category.title"=>"search"
}
}
}
},
limit: 50
)
I hope this got you started on the basics. As you might have recognized, the queries and filters can be nested (I am unaware of any limits to the nesting depth, but it will obviously come at some performance cost). For more advanced queries, I hope I can now safely point you towards the Elastic Search docs. Good luck!
Enjoyed this? Follow me on Mastodon or add the RSS, euh ATOM feed to your feed reader.
Dit artikel van murblog van Maarten Brouwers (murb) is in licentie gegeven volgens een Creative Commons Naamsvermelding 3.0 Nederland licentie .