Created
September 21, 2021 09:49
-
-
Save jojosati/eab2657962b8a98203666c85ccc44158 to your computer and use it in GitHub Desktop.
MongoDB connector for Data Studio - aggregation cache (getSchema.gs)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==== getSchema ==== | |
// https://developers.google.com/datastudio/connector/build#define_the_fields_with_getschema | |
// legacy response - https://developers.google.com/datastudio/connector/reference#getschema | |
var RECCOUNT = 'Record_Count'; | |
function schemaFromSample(samples, _fields) { | |
var names = []; | |
var dataTypes = {}; | |
var solveType = function (doc, k, deep, kbase) { | |
var _k = k.replace(/[.]/g, '__') | |
if (kbase) | |
_k = kbase + '__' + _k | |
if (names.indexOf(_k) !== -1) | |
return; | |
var val = objResolve(doc, k.replace(/__/g, '.')) | |
var t = typeof (val) | |
if (['number', 'string', 'boolean'].indexOf(t) !== -1) { | |
names.push(_k); | |
dataTypes[_k] = t.toUpperCase(); | |
return; | |
} | |
if (deep && t == 'object' && val) { | |
Object.keys(val).forEach(function(subk){ | |
solveType (val, subk, deep-1, _k) | |
}) | |
} | |
} | |
var doc | |
for (doc in samples) { | |
doc = samples[doc]; | |
if (_fields && _fields.length) { | |
_fields.forEach(function(k){ | |
var ak = k.replace(/[*]*$/, '') | |
var adeep = k.length - ak.length | |
if (!ak) { | |
Object.keys(doc).forEach(function(k){ solveType(doc, k, adeep) }) | |
return | |
} | |
solveType(doc, ak, adeep) | |
}) | |
continue; | |
} | |
Object.keys(doc).forEach(function(k){ solveType(doc, k, 1) }) | |
} | |
if (_fields && _fields.length) { | |
_fields.forEach(function(k){ | |
if (!/[*]$/.test(k)) { | |
var _k = k.replace(/[.]/g, '__') | |
if (names.indexOf(_k) !== -1) | |
names.push(_k); | |
} | |
}) | |
} | |
// https://developers.google.com/datastudio/connector/reference#field | |
// https://developers.google.com/datastudio/connector/semantics#semantic-type-detection | |
return (names).map(function(k) { | |
var fld = {name: k, dataType: dataTypes[k] || 'STRING'} | |
return fld; | |
}) | |
} | |
function schemaFromConfig (schemaFields) { | |
return schemaFields.map(function(nt) { | |
// split name:type | |
var ntsegs = nt.split(':'); | |
var field = {name: ntsegs[0].replace(/[.]/g, '__'), dataType: (ntsegs[1] || 'STRING').toUpperCase()}; | |
return field; | |
}); | |
} | |
function refreshRawSchema(request, renew) { | |
// get schema with cache | |
var rconfig = request.configParams | |
var cs = configService(rconfig); | |
var schemaFields = cs.list('schemaFields') | |
var schema = schemaFromConfig(schemaFields) | |
if (schema.length && !schema.find(function(sch) { return (/[*]$/.test(sch.name)); })) | |
return schema; | |
var process = function () { | |
// dynamic schema by fetching sample data | |
// var pipeline = cs.pipeline(request.dateRange); | |
var pipeline = cs.pipeline(); | |
pipeline.push({$limit: 20}); // limit sample | |
var samples = cs.fetchData(pipeline); | |
return schemaFromSample(samples, schemaFields); | |
} | |
var schemaCache = cs.cache('schema', {verbose: true}); | |
return schemaCache.race(process, {force: renew}); | |
} | |
function refreshSchema (request, renew) { | |
var schema = refreshRawSchema(request, renew); | |
if (!schema.find(function(fld){ return fld.name == RECCOUNT})) | |
schema.push({name: RECCOUNT, dataType: 'NUMBER'}); | |
return schema; | |
} | |
function getSchema(request) { | |
return {schema: refreshSchema(request, true)}; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment