Mercurial > hg > ng2-query-ismi
view src/app/query.service.js @ 61:6adf95d9a190 webpack
fix missing resultInfo. add column template for WITNESS.
author | Robert Casties <casties@mpiwg-berlin.mpg.de> |
---|---|
date | Mon, 24 Apr 2017 19:39:25 +0200 |
parents | 7b9d616695d3 |
children |
line wrap: on
line source
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var core_1 = require('@angular/core'); var http_1 = require('@angular/http'); //import 'rxjs/Rx'; // import all RxJS operators require('rxjs/add/operator/map'); var app_config_1 = require('./app-config'); var query_mode_1 = require('./query-mode'); var query_state_1 = require('./query-state'); var result_type_1 = require('./result-type'); var ismi_result_types_1 = require('./ismi-result-types'); var ismi_relation_types_1 = require('./ismi-relation-types'); var QueryService = (function () { function QueryService(_http) { this._http = _http; this.typeAttribute = '_type'; this.excludedAttributes = {}; // init query state this.state = new query_state_1.QueryState(); } QueryService.prototype.setup = function (newStateString) { // get list of object types this.setupObjectTypes(); // get state from string if (newStateString) { this.state.setStateFromString(newStateString); } }; QueryService.prototype.getState = function () { return this.state; }; QueryService.prototype.getQueryModes = function (index) { if (index == 0) { return query_mode_1.FIRST_QUERY_MODES; } else { return query_mode_1.QUERY_MODES; } }; /** * return the first set of options for the given query mode. */ QueryService.prototype.getQueryOptions = function (queryMode) { var options = []; if (queryMode == null) return options; if (queryMode.id === 'type_is') { options = this.objectTypes; } else if (queryMode.id === 'relation_is') { options = this.state.resultRelations; } else if (queryMode.id === 'att_contains') { options = this.filterAttributes(this.state.resultAttributes); } else if (queryMode.id === 'att_contains_norm') { options = this.filterAttributes(this.state.resultAttributes, true); } else if (queryMode.id === 'att_num_range') { options = this.filterAttributes(this.state.resultAttributes); } console.debug("getQueryOptions returns: ", options); return options; }; /** * fetch all object types from Neo4j and store in this.objectTypes. */ QueryService.prototype.setupObjectTypes = function () { var _this = this; var query = "MATCH (n) WITH DISTINCT labels(n) AS labels\n UNWIND labels AS label \n RETURN DISTINCT label ORDER BY label"; var res = this.fetchCypherResults([query]); res.subscribe(function (data) { console.debug("neo4j data=", data); _this.objectTypes = data.results[0].data .map(function (elem) { return elem.row[0]; }) .filter(function (elem) { return elem[0] != "_"; }); console.debug("object types=", _this.objectTypes); }, function (err) { return console.error("neo4j error=", err); }, function () { return console.debug('neo4j query Complete'); }); }; /** * Set the query step at index. */ QueryService.prototype.setQueryStep = function (index, step) { this.state.steps[index] = step; }; /** * Create the cypher queries for the current query state. * * Updates the queries for results, attributes and relations. */ QueryService.prototype.createCypherQuery = function () { var queryMatch = ''; var queryWhere = ''; var queryReturn = ''; var queryParams = {}; var resultQuery = ''; var attributesQuery = ''; var outRelsQuery = ''; var inRelsQuery = ''; var returnType = ''; var nIdx = 1; this.state.steps.forEach(function (step, stepIdx) { var mode = step.mode.id; var params = step.params; /* * step: object type is */ if (mode === 'type_is') { queryMatch = "MATCH (n" + nIdx + ":" + params.objectType + ")"; queryWhere = ''; queryReturn = "RETURN n" + nIdx; returnType = 'node'; } /* * step: object id is */ if (mode === 'id_is') { if (!queryMatch) { // first step - use match clause queryMatch = "MATCH (n" + nIdx + " {ismi_id: {att_val" + stepIdx + "}})"; queryParams[("att_val" + stepIdx)] = parseInt(params.value, 10); queryWhere = ''; queryReturn = "RETURN n" + nIdx; returnType = 'node'; } else { // use where clause if (!queryWhere) { queryWhere = 'WHERE '; } else { queryWhere += ' AND '; } queryWhere += "n" + nIdx + ".ismi_id = {att_val" + stepIdx + "}"; queryParams[("att_val" + stepIdx)] = parseInt(params.value, 10); } } /* * step: relation type is */ if (mode === 'relation_is') { nIdx += 1; var rel = params.relationType; if (rel.isOutgoing()) { queryMatch += "-[:`" + rel.getRelType() + "`]->(n" + nIdx + ")"; } else { // inverse relation queryMatch += "<-[:`" + rel.getRelType() + "`]-(n" + nIdx + ")"; } queryReturn = "RETURN DISTINCT n" + nIdx; returnType = 'node'; } /* * step: attribute contains(_norm) */ if (mode === 'att_contains' || mode === 'att_contains_norm') { if (!queryWhere) { queryWhere = 'WHERE '; } else { queryWhere += ' AND '; } if (params.attribute === 'ismi_id') { // ismi_id is integer queryWhere += "n" + nIdx + ".ismi_id = {att_val" + stepIdx + "}"; queryParams[("att_val" + stepIdx)] = parseInt(params.value, 10); } else { if (mode === 'att_contains_norm') { // match _n_attribute with normValue queryWhere += "lower(n" + nIdx + "._n_" + params.attribute + ") CONTAINS lower({att_val" + stepIdx + "})"; queryParams[("att_val" + stepIdx)] = params.normValue; } else { queryWhere += "lower(n" + nIdx + "." + params.attribute + ") CONTAINS lower({att_val" + stepIdx + "})"; queryParams[("att_val" + stepIdx)] = params.value; } } } /* * step: attribute number range */ if (mode === 'att_num_range') { if (!queryWhere) { queryWhere = 'WHERE '; } else { queryWhere += ' AND '; } queryWhere += ("toint(n" + nIdx + "." + params.attribute + ") >= toint({att_nlo" + stepIdx + "})") + (" AND toint(n" + nIdx + "." + params.attribute + ") <= toint({att_nhi" + stepIdx + "})"); queryParams[("att_nlo" + stepIdx)] = params.numLo; queryParams[("att_nhi" + stepIdx)] = params.numHi; } }); // compose query resultQuery = queryMatch + (queryWhere ? '\n' + queryWhere : '') + '\n' + queryReturn; // compose query for attributes of result attributesQuery = queryMatch + ' ' + queryWhere + (" WITH DISTINCT keys(n" + nIdx + ") AS atts") + " UNWIND atts AS att RETURN DISTINCT att ORDER BY att"; // compose query for relations of result outRelsQuery = queryMatch + '-[r]->() ' + queryWhere + ' RETURN DISTINCT type(r)'; inRelsQuery = queryMatch + '<-[r]-() ' + queryWhere + ' RETURN DISTINCT type(r)'; this.state.resultCypherQuery = resultQuery; this.state.cypherQueryParams = queryParams; this.state.attributesCypherQuery = attributesQuery; this.state.outRelsCypherQuery = outRelsQuery; this.state.inRelsCypherQuery = inRelsQuery; this.state.resultTypes = returnType; }; /** * Create and run the cypher queries for the current query state. * * Updates the results and nextQuery attributes and relations. */ QueryService.prototype.runQuery = function () { var _this = this; this.createCypherQuery(); this.state.resultInfo = 'loading...'; /* * run query for result table */ var queries = [this.state.resultCypherQuery]; var params = [this.state.cypherQueryParams]; if (this.state.attributesCypherQuery) { queries.push(this.state.attributesCypherQuery); params.push(this.state.cypherQueryParams); } if (this.state.outRelsCypherQuery) { queries.push(this.state.outRelsCypherQuery); params.push(this.state.cypherQueryParams); } if (this.state.inRelsCypherQuery) { queries.push(this.state.inRelsCypherQuery); params.push(this.state.cypherQueryParams); } var res = this.fetchCypherResults(queries, params); res.subscribe(function (data) { console.debug("neo4j result data=", data); var resIdx = 0; /* * results for result table */ _this.state.results = data.results[resIdx].data.map(function (elem) { return elem.row[0]; }); _this.state.numResults = _this.state.results.length; // count all types var resTypes = {}; _this.state.results.forEach(function (r) { var t = r[_this.typeAttribute]; if (resTypes[t] == null) { resTypes[t] = 1; } else { resTypes[t] += 1; } }); var info = ''; for (var t in resTypes) { info += t + '(' + resTypes[t] + ') '; } info = info.substr(0, info.length - 1); _this.state.resultInfo = info; // save info also in last step _this.state.steps[_this.state.steps.length - 1].resultInfo = info; /* * results for attribute list */ if (_this.state.attributesCypherQuery) { resIdx += 1; var atts = data.results[resIdx].data.map(function (elem) { return elem.row[0]; }); _this.state.resultAttributes = atts; // the following assumes only one type in the result for (var t in resTypes) { _this.state.resultType = result_type_1.getResultType(t, ismi_result_types_1.ISMI_RESULT_TYPES); break; } _this.state.resultColumns = _this.state.resultType.getColumns(atts); } /* * results for relations list */ if (_this.state.outRelsCypherQuery) { // outgoing aka forward relations resIdx += 1; var rels = data.results[resIdx].data.map(function (elem) { return elem.row[0]; }) .filter(function (elem) { return elem[0] != "_"; }) .map(function (elem) { return ismi_relation_types_1.getRelationType(elem, true); }); _this.state.resultRelations = rels; } if (_this.state.inRelsCypherQuery) { // incoming aka reverse relations resIdx += 1; var rels = data.results[resIdx].data.map(function (elem) { return elem.row[0]; }) .filter(function (elem) { return elem[0] != "_"; }) .map(function (elem) { return ismi_relation_types_1.getRelationType(elem, false); }); _this.state.resultRelations = _this.state.resultRelations.concat(rels); } }, function (err) { return console.error("neo4j result error=", err); }, function () { return console.debug('neo4j result query Complete'); }); }; QueryService.prototype.filterAttributes = function (attributes, normalized) { var _this = this; if (normalized === void 0) { normalized = false; } var atts = []; if (normalized) { attributes.forEach(function (att) { if (att.substr(0, 3) == "_n_") { atts.push(att.substr(3)); } }); } else { atts = attributes.filter(function (elem) { return elem[0] != "_" && !_this.excludedAttributes[elem]; }); } return atts; }; /** * Run the given queries on the Neo4J server. * * Returns an Observable with the results. */ QueryService.prototype.fetchCypherResults = function (queries, params) { if (params === void 0) { params = [{}]; } console.debug("fetching cypher queries: ", queries); var headers = new http_1.Headers(); var auth = app_config_1.NEO4J_AUTHENTICATION; headers.append('Authorization', 'Basic ' + btoa(auth.user + ":" + auth.password)); headers.append('Content-Type', 'application/json'); headers.append('Accept', 'application/json'); // put headers in options var opts = { 'headers': headers }; // unpack queries into statements var statements = queries.map(function (q, i) { return { 'statement': q, 'parameters': (params[i]) ? params[i] : {} }; }); // create POST data from query var data = JSON.stringify({ 'statements': statements }); // make post request asynchronously var resp = this._http.post(app_config_1.NEO4J_BASE_URL + '/transaction/commit', data, opts) .map(function (res) { return res.json(); }); // return Observable return resp; }; QueryService = __decorate([ core_1.Injectable(), __metadata('design:paramtypes', [http_1.Http]) ], QueryService); return QueryService; }()); exports.QueryService = QueryService; //# sourceMappingURL=query.service.js.map