Slide 1

Slide 1 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Alexander Reelsen @spinscale [email protected] Making Elasticsearch flexible

Slide 2

Slide 2 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Why extending at all? • Keeping the core small • Tailored functionality • Corner cases • Prevent custom builds

Slide 3

Slide 3 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Plugin basics

Slide 4

Slide 4 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Concepts • Everything is wired via google guice • Plugins allow you to wire in your own implementations • Structure: Zip files in a special format • Loading via es-plugins.properties plugin=org.elasticsearch.plugin.suggest.SuggestPlugin bin/plugin  -­‐install  de.spinscale/elasticsearch-­‐plugin-­‐suggest/0.90.1-­‐0.7

Slide 5

Slide 5 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Creating a plugin public  class  SuggestPlugin  extends  AbstractPlugin  {        public  String  name()  {                return  "suggest";        }        public  String  description()  {                return  "Suggest  Plugin";        }        public  void  onModule(RestModule  restModule)  {                restModule.addRestAction(RestSuggestAction.class);        } }

Slide 6

Slide 6 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Plugin extension points Collection>  modules()  {} Collection>  services()  {} Collection>  indexModules()  {} Collection>   indexServices()  {} Collection>  shardModules()  {} Collection>   shardServices()  {}

Slide 7

Slide 7 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Adding modules public  class  SuggestPlugin  extends  AbstractPlugin  {    public  Collection>  shardModules()  {        Collection>  modules  =                                                                                  Lists.newArrayList();        modules.add(ShardSuggestModule.class);        return  modules;    } }

Slide 8

Slide 8 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Loading via guice public  class  ShardSuggestModule  extends  AbstractModule  {        @Override        protected  void  configure()  {                bind(ShardSuggestService.class).asEagerSingleton();        } }

Slide 9

Slide 9 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Services, ShardServices public  class  SuggestService  extends  AbstractLifecycleComponent  {                private  volatile  Thread  suggestUpdaterThread;        @Inject        public  SuggestService(Settings  settings,  TransportSuggestRefreshAction   suggestRefreshAction,  ClusterService  clusterService,  IndicesService  indicesService)  {                super(settings);        }        protected  void  doStart()  throws  ElasticSearchException  {                        suggestUpdaterThread  =  EsExecutors.daemonThreadFactory(settings,   "suggest_updater").newThread(new  SuggestUpdaterThread());                        suggestUpdaterThread.start();        }        protected  void  doClose()  throws  ElasticSearchException  {                //  stop  thread        } }

Slide 10

Slide 10 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited HTTP REST endpoints public  class  RestSuggestAction  extends  BaseRestHandler  {        @Inject        public  RestSuggestAction(Settings  settings,  Client  client,  RestController  controller)  {                super(settings,  client);                controller.registerHandler(GET,  "/{index}/__suggest",  this);                controller.registerHandler(GET,  "/{index}/{type}/__suggest",  this);                controller.registerHandler(POST,  "/{index}/__suggest",  this);                controller.registerHandler(POST,  "/{index}/{type}/__suggest",  this);        }        @Override        public  void  handleRequest(final  RestRequest  request,  final  RestChannel  channel)  {                //  execute  here        } } callback ready

Slide 11

Slide 11 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited HTTP REST endpoints client.execute(SuggestAction.INSTANCE,  suggestRequest,  new  ActionListener()   {    public  void  onResponse(SuggestResponse  response)  {        try  {            XContentBuilder  builder  =  RestXContentBuilder.restContentBuilder(request);            builder.startObject();            buildBroadcastShardsHeader(builder,  response);            builder.field("suggestions",  response.suggestions());            builder.endObject();            channel.sendResponse(new  XContentRestResponse(request,  OK,  builder));        }  catch  (Exception  e)  {            onFailure(e);        }    }    public  void  onFailure(Throwable  e)  {        handleException(channel,  request,  e);    } });

Slide 12

Slide 12 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Adding own transport actions public  class  SuggestModule  extends  AbstractModule  {    protected  void  configure()  {        bind(TransportSuggestAction.class).asEagerSingleton();        MapBinder  transportActionsBinder  =                        MapBinder.newMapBinder(binder(),  GenericAction.class,   TransportAction.class);        transportActionsBinder.addBinding(SuggestAction.INSTANCE).to(TransportSugg estAction.class).asEagerSingleton();        MapBinder  actionsBinder  =   MapBinder.newMapBinder(binder(),  String.class,  GenericAction.class);        actionsBinder.addBinding(SuggestAction.NAME).toInstance(SuggestAction.INST ANCE);    } }

Slide 13

Slide 13 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Facets

Slide 14

Slide 14 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Facets • Extract data from query {    "query"  :  {          "match_all"  :  {}      },    "facets"  :  {        "countries"  :  {            "georegion"  :  {                "field"  :  "loc",                "region"  :  "countries"                        }        }    } } Type Parser

Slide 15

Slide 15 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited FacetProcessor public  class  GeoRegionFacetProcessor  extends  AbstractComponent  implements  FacetProcessor  {        public  FacetCollector  parse(String  facetName,  XContentParser  parser,                                                                SearchContext  context)  throws  IOException  {                //  some  code  before                while  ((token  =  parser.nextToken())  !=  XContentParser.Token.END_OBJECT)  {                        if  (token  ==  XContentParser.Token.FIELD_NAME)  {                                currentFieldName  =  parser.currentName();                        }  else  if  (token.isValue())  {                                if  ("field".equals(currentFieldName))  {                                        field  =  parser.text();                                }  else  if  ("region".equals(currentFieldName))  {                                        region  =  parser.text();                                }                        }                }                //  ...                return  new  GeoRegionFacetCollector(facetName,  field,  region,  context);        } }

Slide 16

Slide 16 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited FacetProcessor public  class  GeoRegionFacetProcessor  extends  AbstractComponent  implements  FacetProcessor  {    public  Facet  reduce(String  facetName,  List  facets)  {        GeoRegionFacet  geoRegionFacet  =  (GeoRegionFacet)  facets.get(0);        for  (int  i  =  1  ;  i  <  facets.size()  ;  i++)  {            Facet  facet  =  facets.get(i);            if  (facet  instanceof  GeoRegionFacet)  {                GeoRegionFacet  regionFacet  =  (GeoRegionFacet)  facet;                for  (Map.Entry  entry  :  regionFacet.counts().entrySet())  {                    if  (geoRegionFacet.counts().containsKey(entry.getKey()))  {                        geoRegionFacet.counts().get(entry.getKey()).addAndGet(entry.getValue().longValue ());                    }  else  {                        geoRegionFacet.counts().put(entry.getKey(),  entry.getValue());                    }                }            }        }        return  geoRegionFacet;    } }

Slide 17

Slide 17 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited FacetCollector public  class  GeoRegionFacetCollector  extends  AbstractFacetCollector  implements   FieldData.StringValueInDocProc  {    public  void  onValue(int  docId,  String  value)  {        double[]  location  =  GeoHashUtils.decode(value);        Point  point  =  ShapeBuilder.newPoint(location[0],  location[1]);        for  (Map.Entry  entry  :  GeoRegionService.shapes.get(region).entrySet())  {            if  (entry.getValue().relate(point)  ==  SpatialRelation.CONTAINS)  {                addOrIncrement(entry.getKey());                return;            }        }        addOrIncrement("_unknown");    }    public  void  onMissing(int  docId)  {        addOrIncrement("_missing");    } }

Slide 18

Slide 18 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Facet registration public  class  GeoRegionFacetPlugin  extends  AbstractPlugin  {        //  plugin  name,  description,  setup  here        ...        public  void  onModule(FacetModule  facetModule)  {                facetModule.addFacetProcessor(GeoRegionFacetProcessor .class);        } }

Slide 19

Slide 19 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Mapping

Slide 20

Slide 20 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Mapper public  class  MapperAttachmentsPlugin  extends  AbstractPlugin  {        public  String  name()  {                return  "mapper-­‐attachments";        }        public  String  description()  {                return  "Adds  the  attachment  type  allowing  to  parse  difference   attachment  formats";        }        public  Collection>  indexModules()  {                Collection>  modules  =  newArrayList();                modules.add(AttachmentsIndexModule.class);                return  modules;        } }

Slide 21

Slide 21 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Mapper public  class  AttachmentsIndexModule  extends  AbstractModule  {        @Override        protected  void  configure()  {                bind(RegisterAttachmentType.class).asEagerSingleton();        } } public  class  RegisterAttachmentType  extends  AbstractIndexComponent  {    @Inject    public  RegisterAttachmentType(Index  index,  @IndexSettings  Settings  indexSettings,   MapperService  mapperService)  {        super(index,  indexSettings);        mapperService.documentMapperParser().putTypeParser("attachment",                                                                            new  AttachmentMapper.TypeParser());        } }

Slide 22

Slide 22 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Mapper { "person" : { "properties" : { "my_attachment" : { "type" : "attachment" } } } } public  class  RegisterAttachmentType  extends  AbstractIndexComponent  {    @Inject    public  RegisterAttachmentType(Index  index,  @IndexSettings  Settings  indexSettings,   MapperService  mapperService)  {        super(index,  indexSettings);        mapperService.documentMapperParser().putTypeParser("attachment",                                                                            new  AttachmentMapper.TypeParser());        } } Mapping Type

Slide 23

Slide 23 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Mapper public  class  AttachmentMapper  implements  Mapper  {    public  String  name()  {  return  "attachment";  }    public  void  parse(ParseContext  context)  throws  IOException  {}    public  void  merge(Mapper  mergeWith,  MergeContext  mergeContext)  throws   MergeMappingException  {}    public  XContentBuilder  toXContent(XContentBuilder  builder,  Params  params)  throws   IOException  {} } public  static  class  TypeParser  implements  Mapper.TypeParser  {    public  Mapper.Builder  parse(String  name,  Map  node,  ParserContext   parserContext)  throws  MapperParsingException  {    } }

Slide 24

Slide 24 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Mapper public  static  class  TypeParser  implements  Mapper.TypeParser  {        public  Mapper.Builder  parse(String  name,  Map  node,                                                              ParserContext  parserContext)  throws  MapperParsingException  {    } } curl  -­‐X  PUT  http://localhost:9200/foo/bar/_mapping  -­‐d  '{ "person"  :  {        "properties"  :  {            "foo"  :  {                "type"  :  "attachment"            }        }    } }' PUT Mapping calls parse()

Slide 25

Slide 25 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Mapper public  class  AttachmentMapper  implements  Mapper  {    public  String  name()  {  return  "attachment";  }    public  void  parse(ParseContext  context)  throws  IOException  {}    public  void  merge(Mapper  mergeWith,  MergeContext  mergeContext)  throws   MergeMappingException  {}    public  XContentBuilder  toXContent(XContentBuilder  builder,  Params  params)  throws   IOException  {} } curl  -­‐X  GET  http://localhost:9200/foo/bar/_mapping GET Mapping calls toXContent()

Slide 26

Slide 26 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Mapper public  class  AttachmentMapper  implements  Mapper  {    public  String  name()  {  return  "attachment";  }    public  void  parse(ParseContext  context)  throws  IOException  {}    public  void  merge(Mapper  mergeWith,  MergeContext  mergeContext)  throws   MergeMappingException  {}    public  XContentBuilder  toXContent(XContentBuilder  builder,  Params  params)  throws   IOException  {} } curl  -­‐X  PUT  http://localhost:9200/foo/bar/_mapping  -­‐d  ' { "person"  :  {  "properties"  :  {  "foo"  :  {  "type"  :  "attachment"  }  }  }  }' Mapping Update calls merge()

Slide 27

Slide 27 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Mapper public  class  AttachmentMapper  implements  Mapper  {    public  String  name()  {  return  "attachment";  }    public  void  parse(ParseContext  context)  throws  IOException  {}    public  void  merge(Mapper  mergeWith,  MergeContext  mergeContext)  throws   MergeMappingException  {}    public  XContentBuilder  toXContent(XContentBuilder  builder,  Params  params)  throws   IOException  {} } curl  -­‐X  PUT  http://localhost:9200/foo/bar/1  -­‐d  ' { "foo"  :  "BASE_64_ENCODED"  }' Index operation calls parse()

Slide 28

Slide 28 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Highlighting

Slide 29

Slide 29 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Highlighters public  class  MyHighlightPlugin  extends  AbstractPlugin  {    //  plugin  name,  description,  setup  here    public  void  onModule(HighlightModule  highlightModule)  {        highlightModule.registerHighlighter(MyHighlighter.class);    } }

Slide 30

Slide 30 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Highlighters public  class  MyHighlighter  implements  Highlighter  {        @Override        public  String[]  names()  {                return  new  String[]  {  "my",  "my-­‐highlighter"  };        }        public  HighlightField  highlight(HighlighterContext  highlighterContext)  {        } } {        "query"  :  {...},        "highlight"  :  {                "type"  :  "my-­‐highlighter",                "fields"  :  {  "content"  :  {}  }        } } Type

Slide 31

Slide 31 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Suggest

Slide 32

Slide 32 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Suggester public  class  MySuggestPlugin  extends  AbstractPlugin  {    //  plugin  name,  description,  setup  here    public  void  onModule(SuggestModule  suggestModule)  {        suggestModule.registerSuggester(MySuggester.class);    } }

Slide 33

Slide 33 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Suggester public  final  class  MySuggester  implements  Suggester  {        @Override        public  String[]  names()  {                return  new  String[]  {  "my",  "my-­‐suggester"  };        }        @Override        public  SuggestContextParser  getContextParser()  {                return  new  MySuggestParser(this);        }        public  TermSuggestion  execute(String  name,  MySuggestionContext  suggestion,  IndexReader   indexReader,  CharsRef  spare)  throws  IOException  {              //  impl  here        } }

Slide 34

Slide 34 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Suggester public  final  class  MySuggestParser  implements  SuggestContextParser  {    private  MySuggester  suggester;    public  MySuggestParser(MySuggester  suggester)  {            this.suggester  =  suggester;    }    public  SuggestionSearchContext.SuggestionContext  parse(XContentParser  parser,   MapperService  mapperService)  throws  IOException  {        //  impl  here    } } curl  -­‐XPOST  'localhost:9200/_suggest'  -­‐d  '{    "my-­‐suggestion"  :  {        "text"  :  "the  amsterdma  meetpu",        "my"  :  {  "field"  :  "body"  }    } }' parse

Slide 35

Slide 35 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Rivers

Slide 36

Slide 36 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Rivers public  class  JsonRiverPlugin  extends  AbstractPlugin  {        public  String  name()  {                return  "json";        }        public  String  description()  {                return  "River  Streaming  JSON  Plugin";        }        public  void  onModule(RiversModule  module)  {                module.registerRiver("json",  JsonRiverModule.class);        } } public  class  JsonRiverModule  extends  AbstractModule  {        protected  void  configure()  {                bind(River.class).to(JsonRiver.class).asEagerSingleton();        } }

Slide 37

Slide 37 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Rivers public  class  JsonRiver  extends  AbstractRiverComponent  implements  River  {    private  volatile  Thread  slurperThread;    private  volatile  Thread  indexerThread;    private  final  TransferQueue  stream  =  new  LinkedTransferQueue();    @Override    public  void  start()  {        //  start  both  threads        //  hand  over  transferqueue    }    @Override    public  void  close()  {    } }

Slide 38

Slide 38 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Rivers private  class  Indexer  implements  Runnable  {        private  BulkRequestBuilder  bulk;        public  void  run()  {                while  (!closed)  {                        try  {                                RiverProduct  product  =  stream.take();                                bulk  =  client.prepareBulk();                                do  {                                        addProductToBulkRequest(product);                                }  while  ((product  =  stream.poll(250,  TimeUnit.MILLISECONDS))  !=  null  &&   deletedDocuments  +  insertedDocuments  <  RIVER_MAX_BULK_SIZE);                        }  catch  (InterruptedException  e)  {                                continue;                        }  finally  {                                bulk.execute().actionGet();                        }                }        } } blocking

Slide 39

Slide 39 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Rivers private  class  Indexer  implements  Runnable  {        private  BulkRequestBuilder  bulk;        public  void  run()  {                while  (!closed)  {                        try  {                                RiverProduct  product  =  stream.take();                                bulk  =  client.prepareBulk();                                do  {                                        addProductToBulkRequest(product);                                }  while  ((product  =  stream.poll(250,  TimeUnit.MILLISECONDS))  !=  null  &&   deletedDocuments  +  insertedDocuments  <  RIVER_MAX_BULK_SIZE);                        }  catch  (InterruptedException  e)  {                                continue;                        }  finally  {                                bulk.execute().actionGet();                        }                }        } } wait for new data in stream

Slide 40

Slide 40 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Rivers private  class  Indexer  implements  Runnable  {        private  BulkRequestBuilder  bulk;        public  void  run()  {                while  (!closed)  {                        try  {                                RiverProduct  product  =  stream.take();                                bulk  =  client.prepareBulk();                                do  {                                        addProductToBulkRequest(product);                                }  while  ((product  =  stream.poll(250,  TimeUnit.MILLISECONDS))  !=  null  &&   deletedDocuments  +  insertedDocuments  <  RIVER_MAX_BULK_SIZE);                        }  catch  (InterruptedException  e)  {                                continue;                        }  finally  {                                bulk.execute().actionGet();                        }                }        } } make sure bulk request stays small

Slide 41

Slide 41 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Rivers private  class  Indexer  implements  Runnable  {        private  BulkRequestBuilder  bulk;        public  void  run()  {                while  (!closed)  {                        try  {                                RiverProduct  product  =  stream.take();                                bulk  =  client.prepareBulk();                                do  {                                        addProductToBulkRequest(product);                                }  while  ((product  =  stream.poll(250,  TimeUnit.MILLISECONDS))  !=  null  &&   deletedDocuments  +  insertedDocuments  <  RIVER_MAX_BULK_SIZE);                        }  catch  (InterruptedException  e)  {                                continue;                        }  finally  {                                bulk.execute().actionGet();                        }                }        } } make sure bulk request gets executed

Slide 42

Slide 42 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Scripting

Slide 43

Slide 43 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Scripting public  class  JavaScriptPlugin  extends  AbstractPlugin  {        @Override        public  String  name()  {                return  "lang-­‐javascript";        }        @Override        public  String  description()  {                return  "JavaScript  plugin  allowing  to  add  javascript  scripting  support";        }        public  void  onModule(ScriptModule  module)  {                module.addScriptEngine(JavaScriptScriptEngineService.class);        } }

Slide 44

Slide 44 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Scripting public  class  JavaScriptScriptEngineService  extends  AbstractComponent  implements   ScriptEngineService  {        public  void  close()  {}        public  String[]  types()  {  return  new  String[]{"js",  "javascript"};  }        public  String[]  extensions()  {  return  new  String[]{"js"};  }        public  Object  compile(String  script)  {}        public  ExecutableScript  executable(Object  compiledScript,  Map  vars)  {}        public  SearchScript  search(Object  compiledScript,  SearchLookup  lookup,  @Nullable   Map  vars)  {}        public  Object  execute(Object  compiledScript,  Map  vars)  {}        public  Object  unwrap(Object  value)  {} }

Slide 45

Slide 45 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Tokenizer, Filter & Analyzer

Slide 46

Slide 46 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Analyzer public  class  PolishIndicesAnalysis  extends  AbstractComponent  {    @Inject    public  PolishIndicesAnalysis(Settings  settings,  IndicesAnalysisService   indicesAnalysisService)  {        super(settings);        indicesAnalysisService.analyzerProviderFactories().put("default",              new  PreBuiltAnalyzerProviderFactory("default",  AnalyzerScope.INDICES,                  new  PolishAnalyzer(Lucene.ANALYZER_VERSION)              ));    } }

Slide 47

Slide 47 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Analyzer public  class  PolishAnalysisBinderProcessor  extends  AnalysisModule.AnalysisBinderProcessor  {        @Override        public  void  processAnalyzers(AnalyzersBindings  analyzersBindings)  {                analyzersBindings.processAnalyzer("polish",  PolishAnalyzerProvider.class);        } }

Slide 48

Slide 48 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Analyzer public  class  PolishAnalyzerProvider  extends  AbstractIndexAnalyzerProvider  {        private  final  PolishAnalyzer  analyzer;        @Inject        public  PolishAnalyzerProvider(Index  index,  @IndexSettings  Settings  indexSettings,   Environment  env,  @Assisted  String  name,  @Assisted  Settings  settings)  {                super(index,  indexSettings,  name,  settings);                analyzer  =  new  PolishAnalyzer(version,  PolishAnalyzer.getDefaultStopSet());        }        @Override        public  PolishAnalyzer  get()  {                return  this.analyzer;        } } Lucene Analyzer

Slide 49

Slide 49 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Filter public  class  EnglishMorphologyTokenFilterFactory  extends  AbstractTokenFilterFactory  {        private  final  LuceneMorphology  luceneMorph;        @Inject          public  EnglishMorphologyTokenFilterFactory(Index  index,                          @IndexSettings  Settings  indexSettings,  String  name,  Settings  settings)  {                super(index,  indexSettings,  name,  settings);                try  {                        luceneMorph  =  new  EnglishLuceneMorphology();                }  catch  (IOException  ex)  {                        throw  new  ElasticSearchIllegalArgumentException("Unable  to  load  English   morphology  analyzer",  ex);                }        }        public  TokenStream  create(TokenStream  tokenStream)  {                return  new  MorphologyFilter(tokenStream,  luceneMorph);        } }

Slide 50

Slide 50 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Listeners

Slide 51

Slide 51 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Index lifecycle listeners public  void  shardRoutingChanged(IndexShard  indexShard,  @Nullable  ShardRouting  oldRouting,   ShardRouting  newRouting)  { public  void  beforeIndexCreated(Index  index)  {} public  void  afterIndexCreated(IndexService  indexService)  {} public  void  beforeIndexShardCreated(ShardId  shardId)  {} public  void  afterIndexShardCreated(IndexShard  indexShard)  {} public  void  afterIndexShardStarted(IndexShard  indexShard)  {} public  void  beforeIndexClosed(IndexService  indexService)  {} public  void  afterIndexClosed(Index  index)  {} public  void  beforeIndexShardClosed(ShardId  shardId,  @Nullable  IndexShard  indexShard)   public  void  afterIndexShardClosed(ShardId  shardId)  {}

Slide 52

Slide 52 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Tons of listeners • Remember: elasticsearch is async by nature • ClusterStateListener • FieldMapperListener • IndexingOperationListener • LocalNodeMasterListener • RiverClusterStateListener

Slide 53

Slide 53 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Similarity

Slide 54

Slide 54 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Discovery

Slide 55

Slide 55 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Index store

Slide 56

Slide 56 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Transport

Slide 57

Slide 57 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Snippets

Slide 58

Slide 58 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Execute on master only public  class  SuggestUpdaterThread  implements  Runnable  {        @Override        public  void  run()  {                while  (!closed)  {                        DiscoveryNode  node  =  clusterService.localNode();                        boolean  isClusterStarted  =  clusterService.lifecycleState().                                                                              equals(Lifecycle.State.STARTED);                        if  (isClusterStarted  &&  node  !=  null  &&  node.isMasterNode())  {                                suggestRefreshAction.execute(new  SuggestRefreshRequest()).actionGet();                        }                        try  {                                Thread.sleep(suggestRefreshInterval.millis());                        }  catch  (InterruptedException  e1)  {                                continue;                        }                }        } }

Slide 59

Slide 59 text

Copyright Elasticsearch 2013. Copying, publishing and/or distributing without written permission is strictly prohibited Thanks for listening! We’re hiring http://elasticsearch.com/about/jobs/