Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check metakg before query execution and cancel on missing operations #72

Merged
merged 3 commits into from
Nov 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ const InvalidQueryGraphError = require('./exceptions/invalid_query_graph_error')
const debug = require('debug')('bte:biothings-explorer-trapi:main');
const Graph = require('./graph/graph');
const EdgeManager = require('./edge_manager');
const _ = require('lodash');
const QEdge2BTEEdgeHandler = require('./qedge2bteedge');
const LogEntry = require('./log_entry');
const redisClient = require('./redis-client');

exports.InvalidQueryGraphError = InvalidQueryGraphError;
Expand Down Expand Up @@ -108,13 +111,57 @@ exports.TRAPIQueryHandler = class TRAPIQueryHandler {
return handler;
}

async _edgesSupported(qEdges, kg) {
// _.cloneDeep() is resource-intensive but only runs once per query
qEdges = _.cloneDeep(qEdges);
const manager = new EdgeManager(qEdges);
const edgesMissingOps = {};
while (manager.getEdgesNotExecuted()) {
let current_edge = manager.getNext();
const edgeConverter = new QEdge2BTEEdgeHandler([current_edge], kg);
const sAPIEdges = edgeConverter.getSmartAPIEdges(current_edge);
if (!sAPIEdges.length) {
edgesMissingOps[current_edge.qEdge.id] = current_edge.reverse;
}
// assume results so next edge may be reversed or not
current_edge.executed = true;
current_edge.object.entity_count = 1;
current_edge.subject.entity_count = 1;
// this.logs = [...this.logs, ...edgeConverter.logs];
}

const len = Object.keys(edgesMissingOps).length;
// this.logs = [...this.logs, ...manager.logs];
let edgesToLog = Object.entries(edgesMissingOps).map(([edge, reversed]) => {
return reversed
? `(reversed ${edge})`
: `(${edge})`;
});
edgesToLog = edgesToLog.length > 1
? `[${edgesToLog.join(', ')}]`
: `${edgesToLog.join(', ')}`
if (len > 0) {
const terminateLog = `Query Edge${len > 1 ? 's' : ''} ${edgesToLog} ${
len > 1 ? 'have' : 'has'
} no SmartAPI edges. Your query terminates.`;
debug(terminateLog);
this.logs.push(new LogEntry('WARNING', null, terminateLog).getLog());
return false;
} else {
return true;
}
}

async query() {
this._initializeResponse();
debug('Start to load metakg.');
const kg = this._loadMetaKG(this.smartapiID, this.team);
debug('MetaKG successfully loaded!');
let queryEdges = await this._processQueryGraph(this.queryGraph);
debug(`(3) All edges created ${JSON.stringify(queryEdges)}`);
if (!(await this._edgesSupported(queryEdges, kg))) {
return;
}
const manager = new EdgeManager(queryEdges);
while (manager.getEdgesNotExecuted()) {
//next available/most efficient edge
Expand Down
4 changes: 2 additions & 2 deletions src/qedge2bteedge.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ module.exports = class QEdge2BTEEdgeHandler {
* @param {object} kg - SmartAPI Knowledge Graph Object
* @param {object} qEdge - TRAPI Query Edge Object
*/
_getSmartAPIEdges(qEdge, kg = this.kg) {
getSmartAPIEdges(qEdge, kg = this.kg) {
debug(`Subject node is ${qEdge.getSubject().id}`);
debug(`Object node is ${qEdge.getObject().id}`);
this.logs.push(
Expand Down Expand Up @@ -319,7 +319,7 @@ module.exports = class QEdge2BTEEdgeHandler {
async convert(qEdges) {
let bteEdges = [];
await Promise.all(qEdges.map(async (edge) => {
const smartapi_edges = await this._getSmartAPIEdges(edge);
const smartapi_edges = await this.getSmartAPIEdges(edge);
const apis = _.uniq(smartapi_edges.map(api => api.association.api_name));
debug(`${apis.length} APIs being used:`, JSON.stringify(apis));
debug(`${smartapi_edges.length} SmartAPI edges are retrieved....`);
Expand Down