4 notes on elasticsearch terminology used in this project
6 indices[index] contains one or more
7 types[type] contains one or more
8 documents contain one or more
10 each path contains one element of data
11 each path maps to one field
13 eg PUT, "/twitter/tweet/1"
17 message: "You know, for browsing elasticsearch",
26 this is the collection of index data
28 this is the type of document (kind of like a table in sql)
29 1 document: /twitter/tweet/1
30 this is an actual document in the index ( kind of like a row in sql)
31 5 paths: [ ["user"], ["date"], ["message"], ["name","first"], ["name","last"] ]
32 since documents can be heirarchical this maps a path from a document root to a piece of data
33 5 fields: [ "user", "date", "message", "first", "last" ]
34 this is an indexed 'column' of data. fields are not heirarchical
36 the relationship between a path and a field is called a mapping. mappings also contain a wealth of information about how es indexes the field
39 1) a path is stored as an array, the dpath is <index> . <type> . path.join("."),
40 which can be considered the canonical reference for a mapping
41 2) confusingly, es uses the term index for both the collection of indexed data, and the individually indexed fields
42 so the term index_name is the same as field_name in this sense.
46 var data = app.ns("data");
47 var ux = app.ns("ux");
61 "boolean" : "boolean",
63 "multi_field" : "multi_field"
66 var default_property_map = {
67 "string" : { "store" : "no", "index" : "analysed" },
68 "number" : { "store" : "no", "precision_steps" : 4 },
69 "date" : { "store" : "no", "format" : "dateOptionalTime", "index": "yes", "precision_steps": 4 },
70 "boolean" : { "store" : "no", "index": "yes" },
75 // parses metatdata from a cluster, into a bunch of useful data structures
76 data.MetaData = ux.Observable.extend({
78 state: null // (required) response from a /_cluster/state request
82 this.refresh(this.config.state);
84 getIndices: function(alias) {
85 return alias ? this.aliases[alias] : this.indicesList;
87 // returns an array of strings containing all types that are in all of the indices passed in, or all types
88 getTypes: function(indices) {
89 var indices = indices || [], types = [];
90 this.typesList.forEach(function(type) {
91 for(var i = 0; i < indices.length; i++) {
92 if(! this.indices[indices[i]].types.contains(type))
99 refresh: function(state) {
100 // currently metadata expects all like named fields to have the same type, even when from different types and indices
101 var aliases = this.aliases = {};
102 var indices = this.indices = {};
103 var types = this.types = {};
104 var fields = this.fields = {};
105 var paths = this.paths = {};
107 function createField( mapping, index, type, path, name ) {
108 var dpath = [ index, type ].concat( path ).join( "." );
109 var field_name = mapping.index_name || path.join( "." );
110 var field = paths[ dpath ] = fields[ field_name ] || $.extend({
111 field_name : field_name,
112 core_type : coretype_map[ mapping.type ],
114 }, default_property_map[ coretype_map[ mapping.type ] ], mapping );
116 if (field.type === "multi_field" && typeof field.fields !== "undefined") {
117 for (var subField in field.fields) {
118 field.fields[ subField ] = createField( field.fields[ subField ], index, type, path.concat( subField ), name + "." + subField );
122 field.dpaths.push(dpath);
126 function getFields(properties, type, index, listeners) {
127 (function procPath(prop, path) {
128 for (var n in prop) {
129 if ("properties" in prop[n]) {
130 procPath( prop[ n ].properties, path.concat( n ) );
132 var field = createField(prop[n], index, type, path.concat(n), n);
133 listeners.forEach( function( listener ) {
134 listener[ field.field_name ] = field;
140 for (var index in state.metadata.indices) {
142 types : [], fields : {}, paths : {}, parents : {}
144 indices[index].aliases = state.metadata.indices[index].aliases;
145 indices[index].aliases.forEach(function(alias) {
146 (aliases[alias] || (aliases[alias] = [])).push(index);
148 var mapping = state.metadata.indices[index].mappings;
149 for (var type in mapping) {
150 indices[index].types.push(type);
151 if ( type in types) {
152 types[type].indices.push(index);
155 indices : [index], fields : {}
158 getFields(mapping[type].properties, type, index, [fields, types[type].fields, indices[index].fields]);
159 if ( typeof mapping[type]._parent !== "undefined") {
160 indices[index].parents[type] = mapping[type]._parent.type;
165 this.aliasesList = Object.keys(aliases);
166 this.indicesList = Object.keys(indices);
167 this.typesList = Object.keys(types);
168 this.fieldsList = Object.keys(fields);