StaticElastic:
An ES and BB SPA

Jurgens du Toit / @jrgns

EagerELK

Elasticsearch

Elastic / ELK / Found

Vitals

Architecture

Backbone

SPA: Why Backbone and ES

Why NOT Elasticsearch


They're working on it

StaticElastic


// curl http://localhost:9200/static-elastic/guardian/_search
{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "hits" : {
    "total" : 3938,
    "max_score" : 1.0,
    "hits" : [ {
      "_index" : "static-elastic",
      "_type" : "guardian",
      "_id" : "money-2015-jun-29-digital-banking-mondo-hopes-to-become-the-google-or-facebook-of-the-sector",
      "_score" : 1.0,
      "_source":{"title":"Digital banking:
      //...
                

// curl http://localhost:9200/static-elastic/guardian/business-marketforceslive-2015-jun-29-ocado-jumps-more-than-2-on-hopes-of-international-deal
{
  "_index" : "static-elastic",
  "_type" : "guardian",
  "_id" : "business-marketforceslive-2015-jun-29-ocado-jumps-more-than-2-on-hopes-of-international-deal",
  "_version" : 1,
  "found" : true,
  "fields" : {
    "section" : [ "Business" ],
    "title" : [ "Ocado jumps more than 2% on hopes of international deal" ]
  }
}
          

{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "hits" : {
    "total" : 3938,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "keywords" : {
      "buckets" : [ {
        "key" : "Business",
        "doc_count" : 1298
      }, {
        "key" : "Books",
        "doc_count" : 967
      }, {
      //...
          

// Backbone.Model.Page.sync
sync: function(method, model, options) {
  // Setup CORS
  options || (options = {});
  if (!options.crossDomain) { options.crossDomain = true; }

  // Do "partial" updates and fetch the _source field
  if (method === 'update' || method === 'create') {
    options.data = JSON.stringify({ "doc": model });
    options.type = 'POST';
    options.url  = model.url() + '/_' + method + \
      '?fields=_source&version=' + this.attributes._version;
  }

  return Backbone.Model.prototype.sync.call(
    this, method, model, options
  );
}
          

// Backbone.Model.Page.parse (1)
parse: function(result) {
  if (result.get) {
    // This was from a create or an update
    result._source = result.get._source;
    delete result.get;
  }
  // Use the attributes in the `_source` field for the models attribs
  var model = _.extend(
    this.defaults, result._source ? result._source : {}
  );

  // Set the meta fields
  _.each(this.meta_fields, function(field) {
    if (result[field]) { model[field] = result[field]; }
  });
  //...
          

// Backbone.Model.Page.parse (2)
parse: function(result) {
  //...
  // Check the highlighting
  if (result.highlight) {
    model.highlight = result.highlight;
  }
  //...
          

<!-- Collections Template -->
<% pages.each(function(page) { %>
  
  • <% if (page.attributes.highlight) { %> <%= page.attributes.highlight.title %> <% } else { %> <%= page.attributes.title %> <% } %>
  • <% }) %>
    
    save: function(key, val, options) {
      if (typeof key === 'object') {
        key._version = this.attributes._version;
      }
      return Backbone.Model.prototype.save.call(this, key, val, options);
    },
    
    toJSON: function(options) {
      var data = _.clone(this.attributes);
      // Don't send the meta fields to the server when POST / PUT ing
      _.each(this.meta_fields, function(field) {
        if (data[field]) {
          delete data[field];
        }
      });
      return data;
    }
              
    
    // Backbone.View.Pages
    loadResults: function(evt) {
      var options = {
        remove: false, processData: this.search === '',
        data: { from: this.from }
      };
      if (this.search !== '') {
        options.data.query = { term: { title: this.search } };
        options.data.highlight = {
          pre_tags: [ '' ], post_tags: [ '' ],
          fields: { 'title': {} }
        };
        options.type = 'POST';
        options.data = JSON.stringify(options.data);
      }
      Pages.fetch(options);
    },
              

    Resources

    Questions

    Thanx!

    • jrgns.net
    • EagerELK.com
    • LogstashConfigGuide.com