Mercurial > hg > ng2-query-ismi
view app/query.service.ts @ 15:f84ff6781e57
added att_num_range query type.
author | Robert Casties <casties@mpiwg-berlin.mpg.de> |
---|---|
date | Thu, 21 Jan 2016 17:26:22 +0100 |
parents | 7dc7ea95ca26 |
children | 7d82ca32833c |
line wrap: on
line source
import {Injectable} from 'angular2/core'; import {Http, Headers} from 'angular2/http'; import 'rxjs/Rx'; // import all RxJS operators import {QueryMode, QUERY_MODES} from './query-mode'; import {QueryState} from './query-state'; import {QueryStep} from './query-step'; @Injectable() export class QueryService { public neo4jBaseUrl = 'https://ismi-dev.mpiwg-berlin.mpg.de/neo4j-ismi/db/data'; //public neo4jBaseUrl = 'http://localhost:7474/db/data'; public openMindBaseUrl = 'https://ismi-dev.mpiwg-berlin.mpg.de/om4-ismi/'; //public openMindBaseUrl = 'http://localhost:18080/ismi-richfaces/': public state: QueryState; public ismiObjectTypes: any; constructor(private _http: Http) { this.state = { 'steps': [], 'resultCypherQuery': '', 'cypherQueryParams': {}, 'attributesCypherQuery': '', 'relationsCypherQuery': '', 'results': [], 'resultTypes': '', 'numResults': 0, 'resultInfo': '' }; } setup() { this.setupIsmiObjectTypes(); } getState() { return this.state; } getQueryModes(): QueryMode[] { return QUERY_MODES; } getQueryOptions(queryMode: QueryMode) { var options = []; if (queryMode.id === 'type_is') { options = this.ismiObjectTypes; } else if (queryMode.id === 'relation_is') { options = this.state.nextQueryRelations; } else if (queryMode.id === 'att_contains') { options = this.state.nextQueryAttributes; } else if (queryMode.id === 'att_contains_norm') { options = this.state.nextQueryAttributes; } else if (queryMode.id === 'att_num_range') { options = this.state.nextQueryAttributes; } console.debug("getQueryOptions returns: ", options); return options; } setupIsmiObjectTypes() { var query = `MATCH (n) WITH DISTINCT labels(n) AS labels UNWIND labels AS label RETURN DISTINCT label ORDER BY label`; var res = this.fetchCypherResult(query); res.subscribe( data => { console.debug("neo4j data=", data); this.ismiObjectTypes = data.results[0].data.map(elem => elem.row[0]).filter(elem => elem[0] != "_"); console.debug("ismi types=", this.ismiObjectTypes); }, err => console.error("neo4j error=", err), () => console.debug('neo4j query Complete') ); } setQueryStep(index: number, step: QueryStep) { this.state.steps[index] = step; this.createCypherQuery(); } createCypherQuery() { var queryMatch = ''; var queryWhere = ''; var queryReturn = ''; var queryParams = {}; var resultQuery = ''; var attributesQuery = ''; var relationsQuery = ''; var returnType = ''; var nIdx = 1; this.state.steps.forEach((step, stepIdx) => { /* * step: object type is */ if (step.mode.id === 'type_is') { queryMatch = `MATCH (n${nIdx}:${step.objectType})`; queryWhere = ''; queryReturn = `RETURN n${nIdx}`; returnType = 'node'; } /* * step: relation type is */ if (step.mode.id === 'relation_is') { nIdx += 1; queryMatch += `-[:\`${step.relationType}\`]->(n${nIdx})`; queryReturn = `RETURN n${nIdx}`; returnType = 'node'; } /* * step: attribute contains(_norm) */ if (step.mode.id === 'att_contains' || step.mode.id === 'att_contains_norm') { if (!queryWhere) { queryWhere = 'WHERE '; } else { queryWhere += ' AND '; } if (step.attribute === 'ismi_id') { // ismi_id is integer queryWhere += `n${nIdx}.ismi_id = {att_val${stepIdx}}`; queryParams[`att_val${stepIdx}`] = parseInt(step.value, 10); } else { if (step.mode.id === 'att_contains_norm') { // match _n_attribute with normValue queryWhere += `lower(n${nIdx}._n_${step.attribute}) CONTAINS lower({att_val${stepIdx}})`; queryParams[`att_val${stepIdx}`] = step.normValue; } else { queryWhere += `lower(n${nIdx}.${step.attribute}) CONTAINS lower({att_val${stepIdx}})`; queryParams[`att_val${stepIdx}`] = step.value; } } } /* * step: attribute number range */ if (step.mode.id === 'att_num_range') { if (!queryWhere) { queryWhere = 'WHERE '; } else { queryWhere += ' AND '; } queryWhere += `toint(n${nIdx}.${step.attribute}) >= toint({att_nlo${stepIdx}})` + ` AND toint(n${nIdx}.${step.attribute}) <= toint({att_nhi${stepIdx}})`; queryParams[`att_nlo${stepIdx}`] = step.numLo; queryParams[`att_nhi${stepIdx}`] = step.numHi; } }); resultQuery = queryMatch + '\n' + queryWhere + '\n' + queryReturn; attributesQuery = queryMatch + ' ' + queryWhere + ` WITH DISTINCT keys(n${nIdx}) AS atts` + ` UNWIND atts AS att RETURN DISTINCT att ORDER BY att`; relationsQuery = queryMatch + '-[r]-() ' + queryWhere + ' RETURN DISTINCT type(r)'; this.state.resultCypherQuery = resultQuery; this.state.cypherQueryParams = queryParams; this.state.attributesCypherQuery = attributesQuery; this.state.relationsCypherQuery = relationsQuery; this.state.resultTypes = returnType; } updateQuery() { this.createCypherQuery(); this.state.resultInfo = 'loading...'; // run query for result table var resQuery = this.state.resultCypherQuery; var queryParams = this.state.cypherQueryParams; var resRes = this.fetchCypherResult(resQuery, queryParams); resRes.subscribe( data => { console.debug("neo4j result data=", data); this.state.results = data.results[0].data.map(elem => elem.row[0]); this.state.numResults = this.state.results.length; // count all types var resTypes = {}; this.state.results.forEach((r) => { if (resTypes[r.type] == null) { resTypes[r.type] = 1; } else { resTypes[r.type] += 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; }, err => console.error("neo4j result error=", err), () => console.debug('neo4j result query Complete') ); // run query for attribute list if (this.state.attributesCypherQuery) { var attRes = this.fetchCypherResult(this.state.attributesCypherQuery, queryParams); attRes.subscribe( data => { console.debug("neo4j att data=", data); this.state.nextQueryAttributes = data.results[0].data.map(elem => elem.row[0]).filter(elem => elem[0] != "_");; }, err => console.error("neo4j att error=", err), () => console.debug('neo4j att query Complete') ); } // run query for relations list if (this.state.relationsCypherQuery) { var attRes = this.fetchCypherResult(this.state.relationsCypherQuery, queryParams); attRes.subscribe( data => { console.debug("neo4j rel data=", data); this.state.nextQueryRelations = data.results[0].data.map(elem => elem.row[0]).filter(elem => elem[0] != "_");; }, err => console.error("neo4j rel error=", err), () => console.debug('neo4j rel query Complete') ); } } fetchCypherResult(query: string, params = {}) { console.debug("fetching cypher query: ", query); var headers = new Headers(); headers.append('Authorization', 'Basic ' + btoa('neo4j' + ':' + 'neo5j')); headers.append('Content-Type', 'application/json'); headers.append('Accept', 'application/json'); // put headers in options var opts = {'headers': headers}; // create POST data from query var data = JSON.stringify({'statements': [ {'statement': query, 'parameters': params} ]}); // make post request asynchronously var resp = this._http.post(this.neo4jBaseUrl+'/transaction/commit', data, opts) // filter result as JSON .map(res => res.json()); // return Observable return resp; } fetchNormalizedString(text: string) { console.debug("fetching normalized string: ", text); var headers = new Headers(); headers.append('Accept', 'application/json'); // put headers in options var opts = {'headers': headers}; // make get request asynchronously var url = this.openMindBaseUrl+'jsonInterface?method=normalize_string&type=arabic_translit&text='; url += text; var resp = this._http.get(url, opts) // filter result as JSON .map(res => res.json()); // return Observable return resp; } }