Full Text Search/Exact Search using Match and Filters within Elasticsearch

I decided to dig into those two and put it straight.

When we should use Match and when we should use Filters while using Elasticsearch’s query DSL technic.

But first things first:

Elasticsearch(nowadays called “Elastic”) is very powerful search engine which based on Apache Lucene library.

When we search we gotta be aware into two important aspects: “Full text search” and “Exact Search”

Exact search means that we looking for an exact values. For example:

1. “hello” or “Hello” (mind the caps)

2. Search for a specific username

3. Search for specific date

We using Exact search when we know what we are looking for and we basically looking for one result

With Elasticsearch we can achieve this using the Match query within Query DSL:

  GET /_search
    {

        "query": {
            "match": {

                "Background":"I like to dive"
            }
} }

Now pay attention here.

Match is also can be used for Full Text search(which ill explain next) BUT if we use match and we want to get an exact value results we should use it only when we searching for “non full text search fields”

non full text search fields defined as follow:

  • numbers,
  • A boolean
  • not analysed Strings
  • Date

Dig it?

Now, there is another way to look for an exact values in Elasticsearch and thats using Filters.

Filters answers only yes/no questions and therefor are very useful for exact search terms:

GET /_search
    {

        "query": {
            "filtered": {
"filter": {"term":{"Background":"I like to dive"}} }
} }

Using Filters for exact value strings search put you on the “safe” side without over thinking if your String is analysed or not.

Another concerns to choose Filters (over Match) while doing Exact value searching would be:

1. Caching results (Filter does cache results. Useful in case we going to have similar queries at a time)

2. Hitting less number of docs(Since we looking for an exact values we eventually get less docs)

Next, Let’s make Full Text search clear:

Full text search should be used when we desire to search within texts or when we not sure about the result we are expecting.

Big difference that with full text search we going to get bunch of documents ordered by relevance (Using a scoring system which I wont describe here)

As I described in the beginning, Using the Match with Query DSL is the way to perform Full Text search.

Enjoy your searching,

Idan.

Related Articles:

    (4546)

    How to exclude libraries from all dependencies in Gradle

    I am using Spring boot. Spring boot by default comes with logback. I wanted to use log4j (for whatever reasons..)

    In order to do that I had to exclude logback and add new log4j dependencies:

    logback is “hidden” inside this package:

    
    compile("org.springframework.boot:spring-boot-starter:$project.ext.springBootVersion")
     {
     exclude module: 'org.springframework.boot:spring-boot-starter-logging'
    }
    
    compile("org.springframework.boot:spring-boot-starter-log4j:$project.ext.springBatchVersion")
    
    

    Now when you try to run app you get this Exception:

     SLF4J: Class path contains multiple SLF4J bindings.
    SLF4J: Found binding in [jar:file:/C:/dev/caches/modules-2/files-2.1/org.slf4j/slf4j-log4j12/1.7.10/b3eeae7d1765f988a1f45ea81517191315c69c9e/slf4j-log4j12-1.7.10.jar!/org/slf4j/impl/StaticLoggerBinder.class]
    SLF4J: Found binding in [jar:file:/C:/dev/caches/modules-2/files-2.1/ch.qos.logback/logback-classic/1.1.2/b316e9737eea25e9ddd6d88eaeee76878045c6b2/logback-classic-1.1.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
    

    Now we have to look at Gradle’s dependencies tree to see where logback is hidden in order to eliminate it.

    Simple command to see gradle’s dependencies tree:

    gradle -q dependencies web:dependencies --configuration compile
    
    

    * web stands for your module name.

    snap view of the output:

     Project :web - web
     ------------------------------------------------------------
    
     compile - Compile classpath for source set 'main'.
     +--- org.springframework.boot:spring-boot-starter-actuator:1.2.2.RELEASE
     | +--- org.springframework.boot:spring-boot-starter:1.2.2.RELEASE
     | | +--- org.springframework.boot:spring-boot:1.2.2.RELEASE
     | | | +--- org.springframework:spring-core:4.1.5.RELEASE
     | | | | \--- commons-logging:commons-logging:1.2
     | | | \--- org.springframework:spring-context:4.1.5.RELEASE
     | | | +--- org.springframework:spring-aop:4.1.5.RELEASE
     | | | | +--- aopalliance:aopalliance:1.0
     | | | | +--- org.springframework:spring-beans:4.1.5.RELEASE
     | | | | | \--- org.springframework:spring-core:4.1.5.RELEASE (*)
     | | | | \--- org.springframework:spring-core:4.1.5.RELEASE (*)
     | | | +--- org.springframework:spring-beans:4.1.5.RELEASE (*)
     | | | +--- org.springframework:spring-core:4.1.5.RELEASE (*)
     | | | \--- org.springframework:spring-expression:4.1.5.RELEASE
     | | | \--- org.springframework:spring-core:4.1.5.RELEASE (*)
     | | +--- org.springframework.boot:spring-boot-autoconfigure:1.2.2.RELEASE
     | | | +--- org.springframework.boot:spring-boot:1.2.2.RELEASE (*)
     | | | \--- org.yaml:snakeyaml:1.14
     | | +--- org.springframework.boot:spring-boot-starter-logging:1.2.2.RELEASE
     | | | +--- org.slf4j:jcl-over-slf4j:1.7.10
     | | | | \--- org.slf4j:slf4j-api:1.7.10
     | | | +--- org.slf4j:jul-to-slf4j:1.7.10
     | | | | \--- org.slf4j:slf4j-api:1.7.10
     | | | +--- org.slf4j:log4j-over-slf4j:1.7.10
     | | | | \--- org.slf4j:slf4j-api:1.7.10
     | | | \--- mycompany:logback-classic:1.1.2
     | | | +--- mycompany:logback-core:1.1.2
     | | | \--- org.slf4j:slf4j-api:1.7.6 -> 1.7.10
     | | +--- org.springframework:spring-core:4.1.5.RELEASE (*)
     | | \--- org.yaml:snakeyaml:1.14
     | +--- org.springframework.boot:spring-boot-actuator:1.2.2.RELEASE
    
    

    We can find one of the instances of logback popping up from one of our dependencies:

     mycompany:logback-core:1.1.2

    (I found logback show’s  in other dependencies).

    Now we have two options:

    1.Exclude each logback’s route with-in the indecencies tree

    2.Use configuration-wide exclusion (the easier way)

    So go to your build.gradle and add this:

    
    configurations {
     compile.exclude group:'ch.qos.logback'
    }
    
    

    Thats it. Your nightmare is over.

    if you check the dependencies tree again you wont see any existence of logback anymore

    Idan.

    Related Articles:

    (4546)