+ All Categories
Home > Technology > SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch -...

SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch -...

Date post: 19-Jan-2017
Category:
Upload: sencha
View: 38 times
Download: 0 times
Share this document with a friend
44
Using ExtJS with Elasticsearch Sam Imberman & Karim Besbes
Transcript
Page 1: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

Using ExtJS with Elasticsearch

Sam Imberman & Karim Besbes

Page 2: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

AGENDA

1/ Introduction

Building a faceted catalog of video game assets using ExtJS and Elasticsearch

2/ Walkthrough of our applications

3/ Sharing our experience

4/ Lessons learned

5/ Q & A

Page 3: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

INTRODUCTION

Page 4: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

• The Technology Group is the primary technology partner of game production teams.

• We develop tools, middleware and online solutions used in Ubisoft games.

• Two sister teams- the TG, which is dedicated to developing tools and middleware solutions; and

- the TGO, which develops solutions and manages operations for online gaming.

Ubisoft – Technology GroupWho are we?

Page 5: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

• Flare is “an internal Youtube for Ubisoft”- A video review solution built for Ubisoft game teams to more efficiently collaborate during the

creation of game art assets.

• Portfolio is “an internal Pinterest for Ubisoft”- A search engine for Ubisoft art assets. It enables production to easily find and reuse high quality

assets produced by other Ubisoft studios.

Our productsFlare & Portfolio

Page 6: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

• For artists and animators

• Easy to use

• Same “look and feel”

• Deliver new features fast

• Built on top of ExtJS

Our productsFlare & Portfolio

Page 7: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

• Designer (Sencha Architect) - Rapid prototyping for R&D

• Browser compatibility

• Data stores / Services / REST

• Routing

• Theming

• Build system

A Javascript Framework Why ExtJS ?

Page 8: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

• Document oriented search engine• Distributed, multi-tenant, shards

• RESTful

• Extensible

• Faster aggregations than SQL! Faceting!

• Runs inside many turnkey systems that have a search component

An internal search engineWhat is Elasticsearch?

Page 9: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

An internal search engineQuery language in JSON

Page 10: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

• ES output is not good ExtJS input

• The client does not issue searches- ES is used in the back-end

• ExtJS is good to display information which is derived from ES data- Large search results are easily represented by grids, treegrids, etc

An internal search engineUsing ES with ExtJS

Page 11: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

DEMO APPLICATION & WALKTHROUGH

Page 12: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

Flare and Portfolio Walkthrough

• Flare uses Ext JS 5.x

• Portfolio uses Ext JS 6.x

Page 13: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

SHARING OUR EXPERIENCE

Page 14: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

• The scheduler updates too soon to catch dirty bound values

• notify() to update dirty bound values

View models & storesScheduler overview

var panel = Ext.create('Ext.panel.Panel', { layout: 'fit', viewModel: vm, bind: { title: '{foo}' }, renderTo: Ext.getBody()});

var vm = new Ext.app.ViewModel({ data: { foo: 'cool' }});

panel.getTitle(); // null vm.notify(); panel.getTitle(); // cool vm.set('foo', 'very cool'); panel.getTitle(); // cool Ext.defer(function() { panel.getTitle(); // very cool }, 5);

Karim Besbes
Added jsfiddle to explain the notifier
Karim Besbes
missing store example.
Page 15: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

• ViewModel Store that has autoload = false and a bind descriptor in the URL is not processed by the ViewModel mechanism

View models & storesScheduler overview

var vm = new Ext.app.ViewModel({ data: { username: 'sencha' }, stores: { Profile: { autoLoad: false, fields: ["id", "wtv"], proxy: { type: 'ajax', url: 'api/v1/{username}/profile', reader: { type: 'json' } } } }});

var view = Ext.create('Ext.view.View', { viewModel: vm, tpl: new Ext.XTemplate( '<tpl for=".">', '<div class="selector"></div>', '</tpl>'), itemSelector: 'div', bind : { store: '{Profile}' }});vm.getStore('Profile').load()// Uncaught TypeError: Cannot read property ‘load' of nullvm.notify();vm.getStore('Profile').getProxy().getUrl();// api/v1/sencha/profile

Page 16: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

• What could be easier than writing HTML to build a website?

• Powerful concept for a single page application

• HTML is stored in a string variable

• Full expressiveness of any CSS layout

• Looping structures display DOM based on data, with no ExtJS overhead

XTemplatesUsing HTML in ExtJS layouts

Page 17: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

I can write tables in HTML!

XTemplatesUsing HTML in ExtJS layouts

Page 18: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

XTemplatesInline Editing extension

Page 19: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

• What if the video finishes processing while I’m writing a description?

XTemplatesDon’t override my DOM

Page 20: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

• What happens if the layout run takes place with one of these sections closed?

XTemplatesLayout run fun!

Page 21: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

• The fish is a video turntable

• We want to drag on it to rotate it

• In principle, we’d want to bind to the mousemove and mousedown events of a “video” tag

XTemplatesHow to turn a fish?

Page 22: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

XTemplatesHow to deal with DOM events?

An individual element

Xtemplate container

View

Page 23: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

Capture

Bubble

Xtemplate container

View

An individual element

XTemplatesHow to deal with DOM events?

Page 24: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

Bind events here?

Capture

Bubble

Xtemplate container

View

An individual element

XTemplatesHow to deal with DOM events?

Page 25: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

Bind events here?

Capture

Bubble

Xtemplate container

View

An individual element

XTemplatesHow to deal with DOM events?

Page 26: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

Bind the event with a delegation

// component refers to the container which contains// the template

component.el.dom.addEventListener("mousemove", function(e) { if(e.target.id == "player-video" && e.buttons === 1) {

// . . . }}, true); // true to use capture phase because of video tag

Page 27: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

• ExtJS layout runs don’t know how to deal with templates that change size

• Interactions are not always obvious to develop- Use “onclick=” , or

- Rebind events when regenerating template , or

- Delegate events to parent DOM elements

• But you get absolute flexibility within your layout

XTemplatesCreating interactions?

Page 28: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

• Hard to maintain large chunks of HTML in XTemplates

• Why not load them separately?

• Load templates asynchronously

XTemplatesDynamic loading extension

Page 29: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

//resources/templates/xtemplate.tpl.html

// script.js

• A dynamic template loader library

• Templates are declared in an external HTML file

• Wrapped in a <script> with type=“text/template”

• Easy to read and to maintain

XTemplatesDynamic loading extension

TemplateLoader.TEMPLATES_PATH = "./resources/templates/";

TemplateLoader.require('xtemplate.tpl.html', function (templates) { Ext.create('Ext.panel.Panel', { data : { helloWorld: 'Hello sencha con' }, tpl: templates.get('my-x-template-1') });

Ext.create('Ext.panel.Panel', { data : { anotherHelloWorld: 'Hello sencha con' }, tpl: templates.get('my-x-template-2') });});

<script id=“my-x-template-1” type="text/template"> <p> {helloWorld} </p></script><script id=“my-x-template-2” type="text/template"> <p> {anotherHelloWorld} </p></script>

Page 30: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

Ext JS routingRoute nomenclature

https://portfolio/#!/library?q=couch&weapon=54dab480-e9f8-429a-9bcd-a62800fc9d53• In Portfolio -- IDs in URLs

• In Flare -- values in URLs

facet=GUID query=keyword

https://flare/#!/search?q=couch&uploader=Foo

No normalization required but is not human readable

Human readable but requires normalizationfacet=name query=keyword

Page 31: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

• By default, ExtJS treats query strings as part of routes

• We overrode the routing class’s regular expression, so now routes can accept query strings

Ext JS routingRouting with query strings

// /? -> allows url route to end with or without "/"// (\\?.*) -> allows query string in urlreturn new RegExp('^' + url + '/?(\\?.*)?$', modifiers);

Page 32: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

Ext JS routingThe query data manager

• URL and query string values should be generated and processed by one entry point

• We developed the concept of a query data manager

• A QueryData is a class that processes a query string and provides an interface to interact with

var q1 = "uploader=kbesbes&tag=%23foo&tag=%23boo", q1 = QueryData.fromQueryString(queryString);console.log(q1.getData());

// outputs: Object {uploader: Array[1], tag: Array[2]}

var queryString = "name=sencha&name=%C3%89tudiants", q1 = QueryData.fromQueryString(queryString);q1.getData();// name:// Array[2] 0:"etudiants"// 1:"sencha"q1.addOrRemove('name', 'Étudiants');q1.getData();// name:// Array[1] 0:"sencha"

Example 1:

Example 2:

Example 3: var result, queryString = "con=sencha&year=2016", q1 = QueryData.fromQueryString(queryString), q2 = QueryData.fromQueryString(queryString);

q1.add('speaker', 'karim');q1.toQueryString();// Outputs "con=sencha&year=2016&speaker=karim"result = QueryData.difference(q1,q2);result.toQueryString() ;// Outputs "speaker=karim"

Page 33: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

• Render pages based on a specified route

• Controls facets and filters view based on its query string values

Ext JS routingThe route drives the view

renderMainContent: function(cmp) { var mainContent = Ext.ComponentQuery.query("#main-content")[0]; mainContent.removeAll(true); mainContent.add(cmp); },

onHomepageRouteTrigger: function() { this.renderMainContent(Ext.widget("homeMainContainer"));},

routes: { '!': 'onHomepageRouteTrigger', '!/:tenant/home': 'onTenantHomeRouteTrigger'},

onGalleryRouteTrigger: function(tenant) { this.setTenant(tenant); this.renderMainContent(Ext.widget("galleryMainContainer"));},

Example: http://localhost/#!http://localhost/#!/search?name=foo&since=2015

Page 34: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

• ExtJS assumes 1 endpoint = 1 request = 1 proxy = 1 store

• But in Portfolio, we have data that is often related, but not associated

Display search resultsData model presentation

Page 35: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

Display search resultsOne to one down the line

ResultStore

Proxy

ResultModel

/results/results: { … }facets: { … }

Page 36: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

ResultStore

Proxy

ResultModel

/results/results: { … }facets: { … }

FacetStore

FacetModel

Display search resultsBut let’s make it messier

Page 37: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

// Trigger the load of the facet tree store.var facetTreeStore = this.getViewModel()

.getStore("FacetTreeStore"), response = Ext.JSON.decode(

operation.getResponse().responseText), dataForFacets = this

.generateFacetStoreData(response);

facetTreeStore.setRootNode(dataForFacets);

• Chain-load a second store from a first

Display search resultsChain-loading stores

Page 38: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

The tree we have The tree ExtJS wants"facets":[          {              "path":"assetTypes",            "name":"Asset type",            "label":"Asset Type",            "type":"Facet",            "sortIndex":1,            "expanded":true,            "hasChildren":true,            "children":[                  {                      "value":"21b3a093-b591-409e-a4db-a5990133136d",                    "name":"Wildlife",                    "label":"Wildlife",                    "count":6,                    "filter":"assetTypes/any(e: e/id eq guid'21b3a093-b591-409e-a4db-a5990133136d')",                    "type":"FacetValue",                    "selected":true,                    "expanded":true,                    "hasChildren":true,                    "children":[  …  ]                 }, … ]}, … ]

 [{              "label":"Asset Type",            "value":null,            "checked":null,            "count":null,            "expanded":true,            "leaf":false,            "children":[                  {                      "label":"Wildlife",                    "value":"21b3a093-b591-409e-a4db-a5990133136d",                    "checked":true,                    "count":6,                    "expanded":true,                    "leaf":false,                    "children":[  … ]                 }, … ]}, … ]

Display search resultA tale of two trees

Page 39: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

generateFacetStoreData: function(obj) { // Traverse the facet tree to generate a new tree that will

// work properly with the ExtJS tree store.

return { label: obj.label, value: obj.value || null,

checked: obj.selected, count : Ext.isNumber(obj.count) ? obj.count : null, expanded: obj.expanded,

// If we have no children, mark this node as a leaf. // At top level, "children" node is called "facets". leaf: obj.children ? !obj.children.length : obj.facets ? !obj.facets.length : false,

// Recurse over every child. children: Ext.Array.map( obj.children || obj.facets || [],

function(item, index, array) { return this.generateFacetStoreData(item); }, this) }; }

• API data only contains state of API

• Our API doesn’t look exactly like an ExtJS Tree Panel

Display search resultGenerate tree data locally

Page 40: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

LESSONS LEARNED

Page 41: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

• ExtJS is a relatively good fit for our artistic-yet-enterprise applications

• Don’t fight the tide – use ExtJS for what it does well- Usually it is worth it to massage data to fit into ExtJS views – ‘it just works!’

- Instead of templates, maybe we should start writing components?

Lessons LearnedExt JS framework

Page 42: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

• We have made a lot of incredible extensions, including …

Lessons LearnedExtensions

Page 43: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

Q & A

Page 44: SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS and Elasticsearch - Karim Besbes, Sam Imberman

Recommended