<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Hernan Velasquez</title>
    <description>The latest articles on Forem by Hernan Velasquez (@hernamvel).</description>
    <link>https://forem.com/hernamvel</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F227399%2F3cf89378-2a52-4319-8b6e-1efebd83a670.jpeg</url>
      <title>Forem: Hernan Velasquez</title>
      <link>https://forem.com/hernamvel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/hernamvel"/>
    <language>en</language>
    <item>
      <title>Be careful when using assign_attributes with has_one relations in Rails 7</title>
      <dc:creator>Hernan Velasquez</dc:creator>
      <pubDate>Mon, 30 Oct 2023 07:20:36 +0000</pubDate>
      <link>https://forem.com/hernamvel/be-careful-when-using-assignattributes-with-hasone-relations-in-rails-7-492c</link>
      <guid>https://forem.com/hernamvel/be-careful-when-using-assignattributes-with-hasone-relations-in-rails-7-492c</guid>
      <description>&lt;p&gt;Recently I was tasked to solve a bug on a feature that allows a user to mass import the relationships of an existing record of a model via a yml file.&lt;/p&gt;

&lt;p&gt;Lets say you have 2 models, &lt;code&gt;course&lt;/code&gt; and &lt;code&gt;professor&lt;/code&gt; as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Course &amp;lt; ApplicationRecord
  has_one :professor

  accepts_nested_attributes_for :professor
end

class Professor &amp;lt; ApplicationRecord
  belongs_to :course
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the user can update existing records with a yml like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
name: Math 101
:professor_attributes:
  name: John Doe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The importer just parse this yml into a object like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;params = {
  name: 'Math 101',
  professor_attributes: {
    name: 'John Doe'
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the sake of the example, lets say we want to update course with id 1, so the operation the importer is doing is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;course = Course.find(1)
course.assign_attributes(params)
course.save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It seems pretty straightforward right? Well, unfortunately not in all cases, so let's break this out:&lt;/p&gt;

&lt;h2&gt;
  
  
  A professor's record for existing course doesn't exist:
&lt;/h2&gt;

&lt;p&gt;This case works. If you run this on a rails console you'll get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;course.assign_attributes(params)
course.save

  TRANSACTION (0.2ms)  BEGIN
  Professor Create (3.0ms)  INSERT INTO "professors" ("name", "course_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["name", "John Doe"], ["course_id", 1], ["created_at", "2023-10-30 06:55:41.912606"], ["updated_at", "2023-10-30 06:55:41.912606"]]
  TRANSACTION (2.3ms)  COMMIT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A new record is inserted for the relation and we are all happy.&lt;/p&gt;

&lt;h2&gt;
  
  
  A professor's record for existing course exists, but I don't know it's id:
&lt;/h2&gt;

&lt;p&gt;Here's where things start to get tricky. As you can wonder, the system user doesn't have to know the internals of a database, therefore they don't know the professors primary key. That's why the yml file doesn't have it.&lt;/p&gt;

&lt;p&gt;As we have here a &lt;code&gt;has_one&lt;/code&gt; relation, you can think "well, why do I need to know the professors primary key?  it's only one record anyway!".&lt;/p&gt;

&lt;p&gt;Well, lets see what rails do in this case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;course.assign_attributes(params)

  Professor Load (0.4ms)  SELECT "professors".* FROM "professors" WHERE "professors"."course_id" = $1 LIMIT $2  [["course_id", 1], ["LIMIT", 1]]
  TRANSACTION (0.1ms)  BEGIN
  Professor Update (0.7ms)  UPDATE "professors" SET "course_id" = $1, "updated_at" = $2 WHERE "professors"."id" = $3  [["course_id", nil], ["updated_at", "2023-10-30 07:01:44.880614"], ["id", 5]]
  TRANSACTION (2.6ms)  COMMIT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Weird right? with only calling &lt;code&gt;assign_attributes&lt;/code&gt; rails is going to the database to execute an update setting professor's foreign key to null.&lt;/p&gt;

&lt;p&gt;If then, you run save:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  TRANSACTION (0.2ms)  BEGIN
  Professor Create (0.9ms)  INSERT INTO "professors" ("name", "course_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["name", "John Doe"], ["course_id", 1], ["created_at", "2023-10-30 07:05:05.858188"], ["updated_at", "2023-10-30 07:05:05.858188"]]
  TRANSACTION (1.8ms)  COMMIT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wow, rails is now inserting a new brand record with the "updated" fields, so at the end you will have a duplicated record in the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;select id,name,course_id from professors;

 id |   name   | course_id 
----+----------+-----------
  5 | Jhon Doe |            &amp;lt;- null
  6 | Jhon Doe |         1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So you'll end up 2 records, one of them with its foreign key in null, possibly raising an active record exception if you have strict constraints on the foreign keys.&lt;/p&gt;

&lt;p&gt;This of course will not happen if you include all proper ids in the params hash you are passing to assign_attributes as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;params = {
  name: 'Math 101',
  professor_attributes: {
    id: 5 
    name: 'John Doe'
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Be very careful when using &lt;code&gt;assign_attributes&lt;/code&gt; with &lt;code&gt;accepts_nested_attributes_for&lt;/code&gt;'s models, and don't trust on the fact that has_one relations should be easy to locate. If you can't pass proper primary/foreign keys to the hash object you are passing to &lt;code&gt;assign_attributes&lt;/code&gt; it is better to manually load the relation and update it separately like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;params = {
  name: 'Math 101',
  professor_attributes: {
    name: 'John Doe'
    }
}
course = Course.find(1)
if course.professor
  params[:professor_attributes][:id] = course.id
end
course.assign_attributes(params)
course.save    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hope you find this useful.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>webdev</category>
      <category>database</category>
      <category>development</category>
    </item>
    <item>
      <title>The optimal way to create a set of records with FactoryBot.create_list &amp; FactoryBot.build_list</title>
      <dc:creator>Hernan Velasquez</dc:creator>
      <pubDate>Sat, 19 Jun 2021 09:23:17 +0000</pubDate>
      <link>https://forem.com/hernamvel/the-optimal-way-to-create-a-set-of-records-with-factorybot-createlist-factorybot-buildlist-1j64</link>
      <guid>https://forem.com/hernamvel/the-optimal-way-to-create-a-set-of-records-with-factorybot-createlist-factorybot-buildlist-1j64</guid>
      <description>&lt;h1&gt;
  
  
  The purpose
&lt;/h1&gt;

&lt;p&gt;Recently I advised a fellow Rubyist trying to create 20 records in rspec to change something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# arbitrarily, assign even numbers to employee_number in this example
let(:first) { create (:employee, employee_number: 2) }
let(:second) { create (:employee, employee_number: 4) }
let(:third) { create (:employee, employee_number: 6) }
let(:fourth) { create (:employee, employee_number: 8) }
let(:fifth) { create (:employee, employee_number: 10) }
...
let(:tenth) { create (:employee, employee_number: 20) }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let(:employees) { create_list(:employee, 20) } 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But unfortunately this wasn't that simple, so I want to share this quick write up to expose the problems we faced and the final solution we reached.&lt;/p&gt;

&lt;h1&gt;
  
  
  The uniqueness validation
&lt;/h1&gt;

&lt;p&gt;For the sake of this example, let's build our employee model as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Employee
   validates_uniqueness_of :employee_number
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the migration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   add_column :employees, :employee_number, :integer, default: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So any attempt to call create_list will result in an exception &lt;em&gt;Validation failed: employee_number should be unique&lt;/em&gt; since FactoryBot will try to create the 20 records with this field in 0. Even trying:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let(:employees) { create_list(:employee, 20, employee_number: 20) } 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Will also fail since FactoryBot will try to create the 20 records with this field in 20.&lt;/p&gt;

&lt;h1&gt;
  
  
  First approach, the block
&lt;/h1&gt;

&lt;p&gt;Reading FactoryBot documentation, we found that you can pass a block to create_list to manipulate the record to be created, so our next approach was doing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let(:employees) { 
  create_list(:employee, 20) do |record, i|
    # arbitrarily, assign even numbers to employee_number in this example
    record.employee_number = i * 2
  end
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  First approach failed, why?
&lt;/h1&gt;

&lt;p&gt;Unfortunately FactoryBot folks haven't documented the use of the block properly.  When we read the docs the first time, we believed that create_list was built as something like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def create_list
  object = build the object
  yield(object) if block_given?
  object.save!
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But the way they built this was something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def create_list
  object = build the object
  object.save!
  yield(object) if block_given?
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what we see here is the same effect of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let(:employees) { create_list(:employee, 20) } 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Trying to create 20 employees with employee_number set to its default value, 0, basically because he is saving the object before giving us the opportunity to manipulate the employee_number as we see fit.&lt;/p&gt;

&lt;h1&gt;
  
  
  Second approach, saving in the block.. will it work?
&lt;/h1&gt;

&lt;p&gt;So yeah... next think we thought of was doing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let(:employees) { 
  create_list(:employee, 20) do |record, i|
    # arbitrarily, assign even numbers to employee_number in this example
    record.employee_number = i * 2
    record.save!
  end
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But, this will work?  The answer .....   NOPE...  but, why?&lt;/p&gt;

&lt;p&gt;On the first iteration, it will create an employee with employee_number 0 * 2 = 0&lt;/p&gt;

&lt;p&gt;On the second iteration, expect FactoryBot to create an employee with employee_number 1 * 2 = 2, but as he creates the record before yielding, then it first creates the record with its default (guess what, 0), so yeap, we'll get &lt;em&gt;Validation failed: employee_number should be unique&lt;/em&gt; again.&lt;/p&gt;

&lt;p&gt;Even if we don't have the uniqueness validation, it seems weird to create a persisted object (insert) to immediately update it (update).&lt;/p&gt;

&lt;h1&gt;
  
  
  Third and final approach, using build_list instead.
&lt;/h1&gt;

&lt;p&gt;So, how is the best way to create a set of records using FactoryBot when you have weird validations to take care of?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let(:employees) { 
  build_list(:employee, 20) do |record, i|
    # arbitrarily, assign even numbers to employee_number in this example
    record.employee_number = i * 2
    record.save!
  end
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;build_list was intended to just build the object in memory without persisting them, so we can use it in combination to save! within a block to create the list we wanted without triggering the validations before saving them.&lt;/p&gt;

&lt;p&gt;Its better to use save! instead of save so you will see any other validation error in case it happens to you.&lt;/p&gt;

&lt;p&gt;Happy testing!&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>rspec</category>
      <category>factorybot</category>
    </item>
    <item>
      <title>Understanding and tuning fuzzy queries in ElasticSearch by example</title>
      <dc:creator>Hernan Velasquez</dc:creator>
      <pubDate>Wed, 19 Feb 2020 21:48:08 +0000</pubDate>
      <link>https://forem.com/hernamvel/understanding-and-tuning-fuzzy-queries-in-elasticsearch-by-example-1ci3</link>
      <guid>https://forem.com/hernamvel/understanding-and-tuning-fuzzy-queries-in-elasticsearch-by-example-1ci3</guid>
      <description>&lt;h1&gt;
  
  
  What's a fuzzy query?
&lt;/h1&gt;

&lt;p&gt;Fuzzy queries are one of the most powerful features available in ElasticSearch (ES). It allows to search for similar terms across thousands of documents on an existing index. For example, with fuzzy queries a search term like "colombia" is found on entries like "columbia", "colombie" or "locombia" depending on how tuned we configure the request query.&lt;/p&gt;

&lt;p&gt;Here is assumed that the reader has some basic knowledge on Elasticsearch, in particular how to send query requests to the server. There are a ton of great resources to catch up before going forward with this post.&lt;/p&gt;

&lt;p&gt;To execute fuzzy queries, it's important to understand that ElasticSearch measures similarity using the Levenshtein Edit Distance algorithm, defined as the number of individual changes required to make one term identical to the another one. A change can be an insert, edit or delete operation (ES can also handle transpositions but we'll leave it for another post). It's not that complicated.  Here are two examples:&lt;/p&gt;

&lt;p&gt;The Levenshtein distance between &lt;strong&gt;colombia&lt;/strong&gt; and &lt;strong&gt;columbia&lt;/strong&gt; is 1 because you only need to make one change: change the 'u' for a 'o' in in the term &lt;strong&gt;columbia&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The Levenshtein distance between &lt;strong&gt;colombia&lt;/strong&gt; and &lt;strong&gt;columbi&lt;/strong&gt; is 2 because you only need to make two changes: change the 'u' for a 'o' in in the term &lt;strong&gt;columbia&lt;/strong&gt; and insert an 'a' at the end of the term.&lt;/p&gt;

&lt;h1&gt;
  
  
  Executing a fuzzy query in ElasticSearch
&lt;/h1&gt;

&lt;p&gt;Executing a fuzzy query is not that far from executing a typical search query in ElasticSearch. It's important to add the fuzziness parameter (even the fact that its optional) in the json request with the maximum Levenshtein distance you want to allow. Let's assume we have and index with this documents:&lt;/p&gt;

&lt;p&gt;doc1: "i will marry you because I love you"&lt;br&gt;
doc2: "i will live with harry"&lt;br&gt;
doc2: "i'm sorry for your loss"&lt;/p&gt;

&lt;p&gt;The query&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /_search
{
  "query": {
    "fuzzy": {
      "name": {
        "value": "harry"
        "fuziness": 1
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Will return documents doc1 and doc2 because&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Levenshtein('harry', 'marry') = 1 in doc1&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Levenshtein('harry', 'harry') = 0 in doc2&lt;/strong&gt;&lt;br&gt;
Levenshtein('harry', 'sorry') = 2 in doc2&lt;/p&gt;

&lt;p&gt;Of course, if we change fuziness from 1 to 2, all doc1, doc2 and doc3 documents will be returned.&lt;/p&gt;

&lt;h1&gt;
  
  
  Undestanding "fuziness": "auto"
&lt;/h1&gt;

&lt;p&gt;Sometimes we need more flexibility on how long we want the maximum Levenshtein Distance to be defined. For short terms it makes no sense to have a distance greater that 2 because it can generate a lot of false positives.&lt;/p&gt;

&lt;p&gt;In this sense, ElasticSearch allows the value "auto" to the fuziness parameter that will work in this way:&lt;/p&gt;

&lt;p&gt;If the length of the term is 0, 1 or 2 the maximum Levenshtein distance allowed will be 0. In other words, only terms with exact matches will be returned.&lt;/p&gt;

&lt;p&gt;If the length of the term is 3, 4 or 5 the maximum Levenshtein distance allowed will be 1.&lt;/p&gt;

&lt;p&gt;If the length of the term is greater than 5 the maximum Levenshtein distance allowed will be 2.&lt;/p&gt;

&lt;p&gt;To illustrate this, lets consider this example:&lt;/p&gt;

&lt;p&gt;doc1: "don't be so hard on me"&lt;br&gt;
doc2: "i will live with my friends"&lt;br&gt;
doc2: "love this twitter trends"&lt;/p&gt;

&lt;p&gt;The query&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /_search
{
  "query": {
    "fuzzy": {
      "name": {
        "value": "me"
        "fuziness": "auto"
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Will return doc1 since it has the exact term "me". On doc2 although Levenshtein('me', 'my') = 1, the length of the term is 2 characters so it will be discarded. &lt;/p&gt;

&lt;p&gt;Lets consider this other query over the same documents:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /_search
{
  "query": {
    "fuzzy": {
      "name": {
        "value": "friends"
        "fuziness": "auto"
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This will return:&lt;/p&gt;

&lt;p&gt;doc2 because Levenshtein('friends', 'friends') = 0 (exact match) and length of the term is 6&lt;/p&gt;

&lt;p&gt;doc3 because Levenshtein('friends', 'trends') = 2 (change 'f' -&amp;gt; 'r' and insert 'i' in term 'trends' and length of the term is 6&lt;/p&gt;

&lt;h1&gt;
  
  
  Tuning up "fuziness": "auto"
&lt;/h1&gt;

&lt;p&gt;Although the default definition for auto fuziness in ES is a widely tested and accepted standard, sometimes you'll want to tweak a little bit the relation between Levenshtein Distance and the length of the terms.&lt;/p&gt;

&lt;p&gt;For instance, I find sometimes inconvenient to make fuzzy queries on terms  with length 3, so I'm inclined to look for exact matches on these terms.  To achieve that, we can tweak the query request passing length ranges on the fuzziness entry.  For example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"fuziness": "auto:4,6"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Will work in this way:&lt;/p&gt;

&lt;p&gt;If the length of the term is &lt;strong&gt;0, 1, 2 or 3&lt;/strong&gt; a exact match is expected.&lt;/p&gt;

&lt;p&gt;If the length of the term is &lt;strong&gt;4 or 5&lt;/strong&gt; the maximum Levenshtein distance allowed will be 1.&lt;/p&gt;

&lt;p&gt;If the length of the term is &lt;strong&gt;greater than 5&lt;/strong&gt; the maximum Levenshtein distance allowed will be 2.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;ElasticSearch is a great tool that may be sometime used under its real capabilities.  This small post just wanted to illustrate how fuzzy queries work using simple examples. I hope the reader find this useful.&lt;/p&gt;

</description>
      <category>elasticsearch</category>
      <category>algorithms</category>
      <category>search</category>
    </item>
  </channel>
</rss>
