Michael Born
@michaelborn_me
"CFSearch is a 2010 solution to a 2020 problem"
- Michael Born
"Search via relational database is a 2001 solution to a 2020 problem"
- Michael Born
A 2020 solution to a 2020 problem
A CFML wrapper for ElasticSearch to facilitate:
and configuration
docker run -d \
    -p 9200:9200 \
    -e "discovery.type=single-node" \
     --name="myApp_ES" \
    elasticsearch:7.5.1box install cbelasticsearch// config/Coldbox.cfc
moduleSettings = {
   "cbElasticsearch" : {
       "hosts" : [ {
           "serverProtocol" : "http",
           "serverName"     : "127.0.0.1",
           "serverPort"     : "9200"
       } ],
       "defaultIndex" = "reviews"
   }
}lazy
dog
quick
brown
fox
jumps
over
the
the quick brown fox jumps over the lazy dog
Breaks down keywords into their root
run
running
runners
List of words within a language that are not relevant to most searches
mighty
jungle
in the jungle, the mighty jungle
A definition of fields and field types for a specific index.
{
  "mappings" : {
    "properties" : {
     "primaryTitle"     : { "type" : "text" },
     "titleType"        : { "type" : "keyword" },
     "runtime_mins"     : { "type" : "integer" },
     "startYear"        : { "type" : "integer" },
     "budget"           : { "type" : "integer" },
     "box_office_gross" : { "type" : "integer" }
    }
  }
}A single record within an index
{
   "primaryTitle": "The Fellowship Of The Ring",
   "titleType": "movie",
   "runtime_mins": "178",
   "startYear" : "2001",
   "budget" : "93,000,000",
   "box_office_gross": "887,800,000"
}Creation and management
component {
    /**
     * Initialize the ElasticSearch index on app load/reinit
     */
    void function afterConfigurationLoad( event, interceptData ){
        // create index...
    }
}function buildMyIndex() {
  getInstance( "IndexBuilder@cbElasticsearch" )
      .new(
          "reviews",
         {
            "_doc" = {
                "_all" = { "enabled" = false },
                "properties" = {
                    "title" = { "type" = "text" },
                    "authorName" = { "type" = "integer" },
                    "publishedDate" = { "type" = "text" },
                    "stars" = { "type" = "keyword" },
                    "content" = { "type" = "text" }
                }
            }
        }
  ).save();
}function createBookIndex() {
    getInstance( "IndexBuilder" )
        .new( "books", getInstance( "MappingBuilder@cbElasticSearch" )
            .create( function( mapping ) {
                mapping.text( "title" );
                mapping.object( "author", function( mapping ) {
                    mapping.text( "firstname" );
                    mapping.text( "lastname" );
                } );
            } );
        } );
}function insertReview() {
  
  var bookReview = {
     "title" : "'Phantom': Lost in Hyperspace",
     "authorName" : "Rita Kempley",
     "publishedDate" : DateFormat( "1999-05-19" ),
     "stars" : "1",
     "content" : "The Empire strikes out..."
  };
  
  var document = getInstance( "Document@cbElasticsearch" )
     .new(
         index = "reviews",
         type = "_doc",
         properties = bookReview
     );
  document.save();
  
}with CBElasticsearch
function searchByTitle( required string title ) {
    return getInstance( "SearchBuilder@cbElasticSearch" )
            .new( "news" )
            .match( "title", arguments.title )
            .execute();
}var results = getInstance( "SearchBuilder@CBelasticsearch" )
                .new( "books" )
                .filterMatch( "description", "toast" )
                .execute();var results = getInstance( "SearchBuilder@CBelasticsearch" )
                .new( "books" )
                .match( "description", "toast" )
                .execute();var result = getInstance( "SearchBuilder@cbElasticSearch" )
             .new( "reviews")
             .term( "stars", 5 )
             .execute();var result = getInstance( "SearchBuilder@cbElasticSearch" )
             .new( "reviews" )
             .match( "content", "burnt" )
             .execute();var result = getInstance( "SearchBuilder@cbElasticSearch" )
             .new( "reviews" )
             .mustMatch( "author", "Luis Majano" )
             .mustMatch( "content", "star wars" )
             .execute();var result = getInstance( "SearchBuilder@cbElasticSearch" )
             .new( "reviews" )
             .shouldMatch( "author", "Luis Majano" )
             .shouldMatch( "author", "Jon Clausen" )
             .execute();Building a Yelp sample search
Happy to answer any questions in the CBElasticsearch room