';
249 | if(typeof(caption) === 'string')
250 | {
251 | html += ''+caption+'';
252 | }
253 |
254 | html += '';
255 | html += '';
256 | html += '';
257 | html += ' | ';
258 | html += '';
259 | html += 'MATCH';
260 | html += ' | ';
261 | html += '';
262 | html += 'NOMATCH';
263 | html += ' | ';
264 | html += '';
265 | html += 'EMPTY';
266 | html += ' | ';
267 | html += '';
268 | html += 'ALL';
269 | html += ' | ';
270 | html += '';
271 | html += 'BACKTRACKS';
272 | html += ' | ';
273 | html += '
';
274 |
275 | html += '';
276 | html += '';
277 | html += 'ALT';
278 | html += ' | ';
279 | html += '';
280 | html += this.statsALT.match;
281 | html += ' | ';
282 | html += '';
283 | html += this.statsALT.nomatch;
284 | html += ' | ';
285 | html += '';
286 | html += this.statsALT.empty;
287 | html += ' | ';
288 | html += '';
289 | html += (this.statsALT.match + this.statsALT.nomatch + this.statsALT.empty);
290 | html += ' | ';
291 | html += '';
292 | html += this.statsALT.backtrack;
293 | html += ' | ';
294 | html += '
';
295 |
296 | html += '';
297 | html += '';
298 | html += 'CAT';
299 | html += ' | ';
300 | html += '';
301 | html += this.statsCAT.match;
302 | html += ' | ';
303 | html += '';
304 | html += this.statsCAT.nomatch;
305 | html += ' | ';
306 | html += '';
307 | html += this.statsCAT.empty;
308 | html += ' | ';
309 | html += '';
310 | html += (this.statsCAT.match + this.statsCAT.nomatch + this.statsCAT.empty);
311 | html += ' | ';
312 | html += '';
313 | html += '';
314 | html += ' | ';
315 | html += '
';
316 |
317 | html += '';
318 | html += '';
319 | html += 'REP';
320 | html += ' | ';
321 | html += '';
322 | html += this.statsREP.match;
323 | html += ' | ';
324 | html += '';
325 | html += this.statsREP.nomatch;
326 | html += ' | ';
327 | html += '';
328 | html += this.statsREP.empty;
329 | html += ' | ';
330 | html += '';
331 | html += (this.statsREP.match + this.statsREP.nomatch + this.statsREP.empty);
332 | html += ' | ';
333 | html += '';
334 | html += this.statsREP.backtrack;
335 | html += ' | ';
336 | html += '
';
337 |
338 | html += '';
339 | html += '';
340 | html += 'PRD';
341 | html += ' | ';
342 | html += '';
343 | html += this.statsPRD.match;
344 | html += ' | ';
345 | html += '';
346 | html += this.statsPRD.nomatch;
347 | html += ' | ';
348 | html += '';
349 | html += this.statsPRD.empty;
350 | html += ' | ';
351 | html += '';
352 | html += (this.statsPRD.match + this.statsPRD.nomatch + this.statsPRD.empty);
353 | html += ' | ';
354 | html += '';
355 | html += this.statsPRD.backtrack;
356 | html += ' | ';
357 | html += '
';
358 |
359 | html += '';
360 | html += '';
361 | html += 'RNM';
362 | html += ' | ';
363 | html += '';
364 | html += this.statsRNM.match;
365 | html += ' | ';
366 | html += '';
367 | html += this.statsRNM.nomatch;
368 | html += ' | ';
369 | html += '';
370 | html += this.statsRNM.empty;
371 | html += ' | ';
372 | html += '';
373 | html += (this.statsRNM.match + this.statsRNM.nomatch + this.statsRNM.empty);
374 | html += ' | ';
375 | html += '';
376 | html += '';
377 | html += ' | ';
378 | html += '
';
379 |
380 | html += '';
381 | html += '';
382 | html += 'TRG';
383 | html += ' | ';
384 | html += '';
385 | html += this.statsTRG.match;
386 | html += ' | ';
387 | html += '';
388 | html += this.statsTRG.nomatch;
389 | html += ' | ';
390 | html += '';
391 | html += this.statsTRG.empty;
392 | html += ' | ';
393 | html += '';
394 | html += (this.statsTRG.match + this.statsTRG.nomatch + this.statsTRG.empty);
395 | html += ' | ';
396 | html += '';
397 | html += '';
398 | html += ' | ';
399 | html += '
';
400 |
401 | html += '';
402 | html += '';
403 | html += 'TBS';
404 | html += ' | ';
405 | html += '';
406 | html += this.statsTBS.match;
407 | html += ' | ';
408 | html += '';
409 | html += this.statsTBS.nomatch;
410 | html += ' | ';
411 | html += '';
412 | html += this.statsTBS.empty;
413 | html += ' | ';
414 | html += '';
415 | html += (this.statsTBS.match + this.statsTBS.nomatch + this.statsTBS.empty);
416 | html += ' | ';
417 | html += '';
418 | html += '';
419 | html += ' | ';
420 | html += '
';
421 |
422 | html += '';
423 | html += '';
424 | html += 'TLS';
425 | html += ' | ';
426 | html += '';
427 | html += this.statsTLS.match;
428 | html += ' | ';
429 | html += '';
430 | html += this.statsTLS.nomatch;
431 | html += ' | ';
432 | html += '';
433 | html += this.statsTLS.empty;
434 | html += ' | ';
435 | html += '';
436 | html += (this.statsTLS.match + this.statsTLS.nomatch + this.statsTLS.empty);
437 | html += ' | ';
438 | html += '';
439 | html += '';
440 | html += ' | ';
441 | html += '
';
442 |
443 | html += '';
444 | html += '';
445 | html += 'TOTAL';
446 | html += ' | ';
447 | html += '';
448 | html += total.match;
449 | html += ' | ';
450 | html += '';
451 | html += total.nomatch;
452 | html += ' | ';
453 | html += '';
454 | html += total.empty;
455 | html += ' | ';
456 | html += '';
457 | html += (total.match + total.nomatch + total.empty);
458 | html += ' | ';
459 | html += '';
460 | html += total.backtrack;
461 | html += ' | ';
462 | html += '
';
463 |
464 | html += '';
465 | html += '';
466 | html += ' | ';
467 | html += '';
468 | html += 'RULE NAME';
469 | html += ' | ';
470 | html += '
';
471 |
472 | if(this.statsRules)
473 | {
474 | for(i = 0; i < this.rules.length; i+=1)
475 | {
476 | tot = this.statsRules[i].match + this.statsRules[i].nomatch + this.statsRules[i].empty;
477 | if(tot > 0)
478 | {
479 | html += '';
480 | html += '';
481 | html += ' | ';
482 | html += '';
483 | html += this.statsRules[i].match;
484 | html += ' | ';
485 | html += '';
486 | html += this.statsRules[i].nomatch;
487 | html += ' | ';
488 | html += '';
489 | html += this.statsRules[i].empty;
490 | html += ' | ';
491 | html += '';
492 | html += tot;
493 | html += ' | ';
494 | html += '';
495 | html += this.statsRules[i].rule;
496 | html += ' | ';
497 | html += '
';
498 | }
499 | }
500 | }
501 |
502 | html += '
';
503 | return html;
504 | };
505 |
506 | this.statsALT = [];
507 | this.statsCAT = [];
508 | this.statsREP = [];
509 | this.statsPRD = [];
510 | this.statsRNM = [];
511 | this.statsTRG = [];
512 | this.statsTLS = [];
513 | this.statsTBS = [];
514 | this.statsRules = null;
515 | this.rules = null;
516 | if(isArray(rules))
517 | {
518 | this.rules = rules;
519 | this.statsRules = [];
520 | for(var i = 0; i < this.rules.length; i+=1)
521 | {
522 | this.statsRules[i] = [];
523 | }
524 | }
525 | this.clear();
526 | }
527 |
--------------------------------------------------------------------------------
/lib/apiModelUtility.js:
--------------------------------------------------------------------------------
1 | var snomedLib = require("./snomed");
2 |
3 | module.exports.convertToV1 = function(concept) {
4 | if (typeof concept.module == "string") {
5 | var moduleId = concept.module + "";
6 | concept.module = {
7 | conceptId: moduleId,
8 | preferredTerm: modules[moduleId]
9 | };
10 | }
11 | if (typeof concept.definitionStatus == "string") {
12 | if (concept.definitionStatus == "Primitive") {
13 | concept.definitionStatus = {
14 | conceptId: "900000000000074008",
15 | preferredTerm: "Primitive"
16 | }
17 | } else {
18 | concept.definitionStatus = {
19 | conceptId: "900000000000073002",
20 | preferredTerm: "Defined"
21 | }
22 | }
23 | }
24 | };
25 |
26 | var modules = {}; // Load this modules cache on startup
27 |
28 | module.exports.loadModules = function(databaseName, collectionName) {
29 | snomedLib.loadModules(databaseName, collectionName, function(dbModules) {
30 | modules = dbModules;
31 | console.log("Modules cache initialized");
32 | });
33 | };
--------------------------------------------------------------------------------
/lib/snomed.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by tbertonatti on 11/1/16.
3 | */
4 | var MongoClient = require('mongodb').MongoClient;
5 | var databases = {};
6 | var util = require('util');
7 |
8 | var mongoConnection = process.env['MONGO_DB_CONN'] || "localhost:27017";
9 |
10 | var performMongoDbRequest = function(databaseName, callback) {
11 | if (databases[databaseName]) {
12 | callback(databases[databaseName]);
13 | } else {
14 | //console.log("Connecting");
15 | MongoClient.connect("mongodb://" + mongoConnection + "/" + databaseName, function(err, db) {
16 | if (err) {
17 | console.warn(err.message);
18 | process.exit();
19 | }
20 | //console.log("Connection OK")
21 | databases[databaseName] = db;
22 | callback(db);
23 | });
24 | }
25 | };
26 | var getObject = function(dbP, collectionP, query, options, callback) {
27 | console.log("DB: " + JSON.stringify(dbP));
28 | console.log("Collection: " + JSON.stringify(collectionP));
29 | console.log("Query: " + JSON.stringify(query));
30 | performMongoDbRequest(dbP, function(db) {
31 | var collection = db.collection(collectionP);
32 | console.log("Collection: " + util.inspect(collection));
33 | //var query = { '$or': [ {'conceptId': conceptId }, {'conceptId': parseInt(conceptId) } ]};
34 | //collection.find(query, options).nextObject(function(err, doc) {
35 | collection.find(query, options, function(err, cursor) {
36 | if (err) {
37 | callback(err.message);
38 | } else {
39 | cursor.toArray(function(err, docs) {
40 | if (err) {
41 | callback(err.message);
42 | } else if (docs) {
43 | callback(false, docs);
44 | } else {
45 | callback("Docs not found for = " + JSON.stringify(query));
46 | }
47 | });
48 | }
49 | });
50 | });
51 | };
52 |
53 | var getConcept = function(dbP, collectionP, conceptId, options, callback) {
54 | getObject(dbP, collectionP, { '$or': [{ 'conceptId': conceptId }, { 'conceptId': parseInt(conceptId) }] }, options, function(err, docs) {
55 | if (err) callback(err);
56 | else if (docs) callback(false, docs[0]);
57 | });
58 | };
59 |
60 | var getDescriptions = function(dbP, collectionP, conceptId, descriptionId, options, callback) {
61 | getConcept(dbP, collectionP, conceptId, options, function(err, doc) {
62 | if (err) callback(err);
63 | else if (doc) {
64 | var result = [];
65 | doc.descriptions.forEach(function(desc) {
66 | if (descriptionId) {
67 | if (parseInt(descriptionId) == desc.descriptionId || descriptionId == desc.descriptionId) {
68 | result.push(desc);
69 | }
70 | } else {
71 | result.push(desc);
72 | }
73 | });
74 | callback(false, result);
75 | }
76 | });
77 | };
78 |
79 | var getRelationShips = function(dbP, collectionP, conceptId, form, options, callback) {
80 | getConcept(dbP, collectionP, conceptId, options, function(err, doc) {
81 | if (err) callback(err);
82 | else if (doc) {
83 | var result = [];
84 | if (form == "all" || form == "inferred") {
85 | doc.relationships.forEach(function(desc) {
86 | result.push(desc);
87 | });
88 | }
89 | if (form == "all" || form == "stated") {
90 | doc.statedRelationships.forEach(function(desc) {
91 | result.push(desc);
92 | });
93 | }
94 | callback(false, result);
95 | }
96 | });
97 | };
98 |
99 | var getParents = function(dbP, collectionP, conceptId, form, options, callback) {
100 | getConcept(dbP, collectionP, conceptId, options, function(err, doc) {
101 | if (err) callback(err);
102 | else if (doc) {
103 | var result = [];
104 | if (typeof doc.relationships != 'undefined') {
105 | if (form) {
106 | if (form == "inferred" && doc.relationships) {
107 | doc.relationships.forEach(function(rel) {
108 | if (rel.active == true && (rel.type.conceptId == 116680003 || rel.type.conceptId == "116680003")) {
109 | result.push({ conceptId: rel.target.conceptId, defaultTerm: rel.target.defaultTerm, definitionStatus: rel.target.definitionStatus, module: rel.target.module, statedDescendants: rel.target.statedDescendants, inferredDescendants: rel.target.inferredDescendants });
110 | }
111 | });
112 | } else if (form == "stated" && doc.statedRelationships) {
113 | doc.statedRelationships.forEach(function(rel) {
114 | if (rel.active == true && (rel.type.conceptId == 116680003 || rel.type.conceptId == "116680003")) {
115 | result.push({ conceptId: rel.target.conceptId, defaultTerm: rel.target.defaultTerm, definitionStatus: rel.target.definitionStatus, module: rel.target.module, statedDescendants: rel.target.statedDescendants, inferredDescendants: rel.target.inferredDescendants });
116 | }
117 | });
118 | }
119 | } else if (doc.relationships) {
120 | doc.relationships.forEach(function(rel) {
121 | if (rel.active == true && (rel.type.conceptId == 116680003 || rel.type.conceptId == "116680003")) {
122 | result.push({ conceptId: rel.target.conceptId, defaultTerm: rel.target.defaultTerm, definitionStatus: rel.target.definitionStatus, module: rel.target.module });
123 | }
124 | });
125 | }
126 | }
127 | callback(false, result);
128 | }
129 | });
130 | };
131 |
132 | var getMembers = function(dbP, collectionP, conceptId, options, callback) {
133 | var query = { "memberships": { "$elemMatch": { "refset.conceptId": conceptId, "active": true } } };
134 | if (options.filter) {
135 | var searchTerm = "\\b" + regExpEscape(options.filter).toLowerCase();
136 | query.defaultTerm = { "$regex": searchTerm, "$options": "i" };
137 | }
138 | if (options.activeOnly == "true") {
139 | query.active = "true";
140 | }
141 | //console.log(JSON.stringify(query));
142 | var getTotalOf = function(refsetId, callback) {
143 | getObject("server", "resources", { "databaseName": dbP, "collectionName": collectionP.replace("v", "") }, { refsets: 1 }, function(err, docs) {
144 | if (err) {
145 | callback(err);
146 | } else {
147 | var total = 0,
148 | error = "No refset matching in the manifest";
149 | docs[0].refsets.forEach(function(refset) {
150 | if (refset.conceptId == refsetId) {
151 | error = false;
152 | total = refset.count;
153 | }
154 | });
155 | callback(error, total);
156 | }
157 | });
158 | };
159 | getTotalOf(conceptId, function(err, totalR) {
160 | var total = totalR;
161 | if (err) total = err;
162 | getObject(dbP, collectionP, query, options, function(err, docs) {
163 | if (err) callback(err);
164 | else {
165 | var result = {};
166 | result.members = [];
167 | result.details = { 'total': total, 'refsetId': conceptId };
168 | if (docs && docs.length > 0)
169 | result.members = docs;
170 | callback(false, result);
171 | }
172 | });
173 | });
174 | };
175 |
176 | var searchDescription = function(dbP, collectionP, filters, query, options, callback) {
177 | console.log("Search", JSON.stringify(query));
178 | var start = Date.now();
179 | var processMatches = function(docs) {
180 | var dbDuration = Date.now() - start;
181 | var result = {};
182 | result.matches = [];
183 | result.details = { 'total': 0, 'skipTo': filters.skipTo, 'returnLimit': filters.returnLimit };
184 | result.filters = {};
185 | result.filters.lang = {};
186 | result.filters.semTag = {};
187 | result.filters.module = {};
188 | result.filters.refsetId = {};
189 | if (docs && docs.length > 0) {
190 | result.details = { 'total': docs.length, 'skipTo': filters.skipTo, 'returnLimit': filters.returnLimit };
191 | if (filters.idParamStr == docs[0].descriptionId) {
192 | result.matches.push({ "term": docs[0].term, "conceptId": docs[0].conceptId, "active": docs[0].active, "conceptActive": docs[0].conceptActive, "fsn": docs[0].fsn, "module": docs[0].module });
193 | callback(false, result);
194 | } else {
195 | var matchedDescriptions = docs.slice(0);
196 | if (filters.searchMode == "regex" || filters.searchMode == "partialMatching") {
197 | matchedDescriptions.sort(function(a, b) {
198 | if (a.term.length < b.term.length)
199 | return -1;
200 | if (a.term.length > b.term.length)
201 | return 1;
202 | return 0;
203 | });
204 | }
205 | var count = 0;
206 | var conceptIds = [];
207 | matchedDescriptions.forEach(function(doc) {
208 | var refsetOk = false;
209 | if (doc.refsetIds) {
210 | doc.refsetIds.forEach(function(refset) {
211 | if (refset == filters.refsetFilter) {
212 | refsetOk = true;
213 | }
214 | });
215 | }
216 | if (filters.semanticFilter == "none" || (filters.semanticFilter == doc.semanticTag)) {
217 | if (filters.langFilter == "none" || (filters.langFilter == doc.lang)) {
218 | if (filters.moduleFilter == "none" || (filters.moduleFilter == doc.module)) {
219 | if (filters.refsetFilter == "none" || refsetOk) {
220 | if (!filters["groupByConcept"] || conceptIds.indexOf(doc.conceptId) == -1) {
221 | conceptIds.push(doc.conceptId);
222 |
223 | if (count >= filters.skipTo && count < (filters.skipTo + filters.returnLimit)) {
224 | result.matches.push({ "term": doc.term, "conceptId": doc.conceptId, "active": doc.active, "conceptActive": doc.conceptActive, "fsn": doc.fsn, "module": doc.module, "definitionStatus": doc.definitionStatus });
225 | }
226 | if (result.filters.semTag.hasOwnProperty(doc.semanticTag)) {
227 | result.filters.semTag[doc.semanticTag] = result.filters.semTag[doc.semanticTag] + 1;
228 | } else {
229 | result.filters.semTag[doc.semanticTag] = 1;
230 | }
231 | if (result.filters.lang.hasOwnProperty(doc.lang)) {
232 | result.filters.lang[doc.lang] = result.filters.lang[doc.lang] + 1;
233 | } else {
234 | result.filters.lang[doc.lang] = 1;
235 | }
236 | if (result.filters.module.hasOwnProperty(doc.module)) {
237 | result.filters.module[doc.module] = result.filters.module[doc.module] + 1;
238 | } else {
239 | result.filters.module[doc.module] = 1;
240 | }
241 | if (doc.refsetIds) {
242 | doc.refsetIds.forEach(function(refset) {
243 | if (result.filters.refsetId.hasOwnProperty(refset)) {
244 | result.filters.refsetId[refset] = result.filters.refsetId[refset] + 1;
245 | } else {
246 | result.filters.refsetId[refset] = 1;
247 | }
248 | });
249 | }
250 | count = count + 1;
251 | }
252 | }
253 | }
254 | }
255 | }
256 | });
257 | result.details.total = count;
258 | callback(false, result);
259 | }
260 | } else {
261 | var duration = Date.now() - start;
262 | result.matches = [];
263 | result.details = { 'total': 0, 'skipTo': filters.skipTo, 'returnLimit': filters.returnLimit };
264 | callback(false, result);
265 | }
266 | };
267 | if (filters.searchMode == "regex" || filters.searchMode == "partialMatching") {
268 | console.log("Entering part match search");
269 | getObject(dbP, collectionP + "tx", query, options, function(err, docs) {
270 | console.log("Result: ", docs.length);
271 | processMatches(docs);
272 | });
273 | } else {
274 | performMongoDbRequest(dbP, function(db) {
275 | var collection = db.collection(collectionP + 'tx');
276 | collection.find(query, { score: { $meta: "textScore" } }).sort({ score: { $meta: "textScore" }, length: 1 }, function(err, cursor) {
277 | if (err) processMatches([]);
278 | else {
279 | cursor.toArray(function(err, docs) {
280 | processMatches(docs);
281 | });
282 | }
283 | });
284 | });
285 | }
286 | };
287 |
288 | var getTime = function() {
289 | var currentdate = new Date();
290 | var datetime = "Last Sync: " + currentdate.getDate() + "/" +
291 | (currentdate.getMonth() + 1) + "/" +
292 | currentdate.getFullYear() + " @ " +
293 | currentdate.getHours() + ":" +
294 | currentdate.getMinutes() + ":" +
295 | currentdate.getSeconds();
296 | return datetime;
297 | };
298 |
299 | module.exports.getObject = getObject;
300 | module.exports.getConcept = getConcept;
301 | module.exports.getDescriptions = getDescriptions;
302 | module.exports.getRelationShips = getRelationShips;
303 | module.exports.getParents = getParents;
304 | module.exports.getMembers = getMembers;
305 | module.exports.searchDescription = searchDescription;
306 |
307 | var regExpEscape = function(s) {
308 | return String(s).replace(/([-()\[\]{}+?*.$\^|,:# 0) {
59 | if (!docs[0].v || docs[0].v != "2") {
60 | callback("The db isnot version 2. It must be created with the new conversion module.");
61 |
62 | } else {
63 | if (v1) {
64 | getDefaultTermType(dbP, collectionP, function(err, defTermType) {
65 | if (err) callback(err);
66 | else {
67 | var result = transform.getV1Concept(docs[0], defTermType);
68 | callback(false, result);
69 | }
70 | });
71 | } else {
72 | callback(false, docs[0]);
73 | }
74 | }
75 | } else {
76 | callback(true, "There are no data for this conceptId:" + conceptId);
77 | }
78 | });
79 | };
80 |
81 | var getDescriptions = function(dbP, collectionP, conceptId, descriptionId, options, callback) {
82 |
83 | var v1;
84 | if (options.v1) {
85 | v1 = true;
86 | delete options.v1;
87 | }
88 | getConcept(dbP, collectionP, conceptId, options, function(err, doc) {
89 | if (err) callback(err);
90 | else if (doc) {
91 | var result = [];
92 | if (!doc.v || doc.v != "2") {
93 | callback("The db isnot version 2. It must be created with the new conversion module.");
94 |
95 | } else {
96 | if (doc.descriptions) {
97 | doc.descriptions.forEach(function(desc) {
98 | if (descriptionId) {
99 | if (descriptionId == desc.descriptionId) {
100 | result.push(desc);
101 | }
102 | } else {
103 | result.push(desc);
104 | }
105 | });
106 | if (v1) {
107 | result = transform.getV1Descriptions(result);
108 | }
109 | }
110 | callback(false, result);
111 | }
112 | }
113 | });
114 | };
115 |
116 | var getRelationShips = function(dbP, collectionP, conceptId, form, options, callback) {
117 |
118 | var v1;
119 | if (options.v1) {
120 | v1 = true;
121 | delete options.v1;
122 | }
123 | getConcept(dbP, collectionP, conceptId, options, function(err, doc) {
124 | if (err) callback(err);
125 | else if (doc) {
126 | var result = [];
127 | if (!doc.v || doc.v != "2") {
128 | callback("The db isnot version 2. It must be created with the new conversion module.");
129 |
130 | } else {
131 | if (doc.relationships) {
132 | doc.relationships.forEach(function(desc) {
133 | if (form == "all") {
134 | result.push(desc);
135 | } else if (form == "inferred" && desc.characteristicType.conceptId == "900000000000011006") {
136 | result.push(desc);
137 | } else if (form == "stated" && desc.characteristicType.conceptId == "900000000000010007") {
138 | result.push(desc);
139 | } else if (form == "additional" && desc.characteristicType.conceptId == "900000000000227009") {
140 | result.push(desc);
141 | }
142 | });
143 | if (v1) {
144 |
145 | getDefaultTermType(dbP, collectionP, function(err, defTermType) {
146 | if (err) callback(err);
147 | else {
148 | result = transform.getV1Relationships(result, defTermType);
149 | callback(false, result);
150 | }
151 | });
152 | } else {
153 | callback(false, result);
154 | }
155 | } else {
156 | callback(false, result);
157 | }
158 | }
159 | }
160 | });
161 | };
162 |
163 | var getParents = function(dbP, collectionP, conceptId, form, options, callback) {
164 |
165 | var v1;
166 | if (options.v1) {
167 | v1 = true;
168 | delete options.v1;
169 | }
170 | getConcept(dbP, collectionP, conceptId, options, function(err, doc) {
171 | if (err) callback(err);
172 | else if (doc) {
173 | var result = [];
174 |
175 | if (!doc.v || doc.v != "2") {
176 | callback("The db isnot version 2. It must be created with the new conversion module.");
177 |
178 | } else {
179 | if (typeof doc.relationships != 'undefined') {
180 | if (form) {
181 | if (form == "inferred" && doc.relationships) {
182 | doc.relationships.forEach(function(rel) {
183 | if (rel.characteristicType.conceptId == "900000000000011006" && rel.active == true && rel.type.conceptId == "116680003") {
184 | result.push({
185 | conceptId: rel.destination.conceptId,
186 | preferredTerm: rel.destination.preferredTerm,
187 | fullySpecifiedName: rel.destination.fullySpecifiedName,
188 | definitionStatus: rel.destination.definitionStatus,
189 | module: rel.destination.module,
190 | statedDescendants: rel.destination.statedDescendants,
191 | inferredDescendants: rel.destination.inferredDescendants
192 | });
193 | }
194 | });
195 | } else if (form == "stated" && doc.relationships) {
196 | doc.relationships.forEach(function(rel) {
197 | if (rel.characteristicType.conceptId == "900000000000010007" && rel.active == true && rel.type.conceptId == "116680003") {
198 | result.push({
199 | conceptId: rel.destination.conceptId,
200 | preferredTerm: rel.destination.preferredTerm,
201 | fullySpecifiedName: rel.destination.fullySpecifiedName,
202 | definitionStatus: rel.destination.definitionStatus,
203 | module: rel.destination.module,
204 | statedDescendants: rel.destination.statedDescendants,
205 | inferredDescendants: rel.destination.inferredDescendants
206 | });
207 | }
208 | });
209 | }
210 | } else if (doc.relationships) {
211 | doc.relationships.forEach(function(rel) {
212 | if (rel.characteristicType.conceptId == "900000000000011006" && rel.active == true && rel.type.conceptId == "116680003") {
213 | result.push({
214 | conceptId: rel.destination.conceptId,
215 | preferredTerm: rel.destination.preferredTerm,
216 | fullySpecifiedName: rel.destination.fullySpecifiedName,
217 | definitionStatus: rel.destination.definitionStatus,
218 | module: rel.destination.module,
219 | statedDescendants: rel.destination.statedDescendants,
220 | inferredDescendants: rel.destination.inferredDescendants
221 | });
222 | }
223 | });
224 | }
225 | if (v1 && result.length > 0) {
226 |
227 | getDefaultTermType(dbP, collectionP, function(err, defTermType) {
228 | if (err) callback(err);
229 | else {
230 | result = transform.getV1ConceptDescriptors(result, defTermType);
231 | callback(false, result);
232 | }
233 | });
234 | } else {
235 | callback(false, result);
236 |
237 | }
238 | } else {
239 | callback(false, result);
240 | }
241 | }
242 | }
243 | });
244 | };
245 |
246 | var getMembers = function(dbP, collectionP, conceptId, options, callback) {
247 |
248 | var v1;
249 | if (options.v1) {
250 | v1 = true;
251 | delete options.v1;
252 | }
253 | var query = { "memberships": { "$elemMatch": { "refset.conceptId": conceptId, "active": true } } };
254 | if (options.filter) {
255 | var searchTerm = "\\b" + regExpEscape(options.filter).toLowerCase();
256 | query.preferredTerm = { "$regex": searchTerm, "$options": "i" };
257 | }
258 | if (options.activeOnly == "true") {
259 | query.active = "true";
260 | }
261 | //console.log(JSON.stringify(query));
262 | var getTotalOf = function(refsetId, callback) {
263 | getObject("server", "resources", { "databaseName": dbP, "collectionName": collectionP.replace("v", "") }, { refsets: 1 }, function(err, docs) {
264 | if (err) {
265 | callback(err);
266 | } else {
267 | var total = 0,
268 | error = "No refset matching in the manifest";
269 | docs[0].refsets.forEach(function(refset) {
270 | if (refset.conceptId == refsetId) {
271 | error = false;
272 | total = refset.count;
273 | }
274 | });
275 | callback(error, total);
276 | }
277 | });
278 | };
279 | getTotalOf(conceptId, function(err, totalR) {
280 | var total = totalR;
281 | if (err) total = err;
282 | getObject(dbP, collectionP, query, options, function(err, docs) {
283 | if (err) callback(err);
284 | else {
285 | var result = {};
286 | result.members = [];
287 | result.details = { 'total': total, 'refsetId': conceptId };
288 | if (docs && docs.length > 0) {
289 | if (!docs[0].v || docs[0].v != "2") {
290 | callback("The db isnot version 2. It must be created with the new conversion module.");
291 |
292 | } else {
293 | result.members = docs;
294 |
295 | if (v1) {
296 |
297 | getDefaultTermType(dbP, collectionP, function(err, defTermType) {
298 | if (err) callback(err);
299 | else {
300 | result.members = transform.getV1ConceptDescriptors(result.members, defTermType);
301 | callback(false, result);
302 | }
303 | });
304 |
305 | } else {
306 | callback(false, result);
307 | }
308 | }
309 | } else {
310 | callback(false, result);
311 | }
312 | }
313 | });
314 | });
315 | };
316 |
317 | var searchDescription = function(dbP, collectionP, filters, query, options, callback) {
318 | console.log("Search", JSON.stringify(query));
319 | var processMatches = function(docs) {
320 | var result = {};
321 | result.matches = [];
322 | result.details = { 'total': 0, 'skipTo': filters.skipTo, 'returnLimit': filters.returnLimit };
323 | result.filters = {};
324 | result.filters.lang = {};
325 | result.filters.semTag = {};
326 | result.filters.module = {};
327 | result.filters.refsetId = {};
328 | if (docs && docs.length > 0) {
329 |
330 | result.details = { 'total': docs.length, 'skipTo': filters.skipTo, 'returnLimit': filters.returnLimit };
331 | if (filters.idParamStr == docs[0].descriptionId) {
332 | result.matches.push({
333 | "term": docs[0].term,
334 | "conceptId": docs[0].conceptId,
335 | "active": docs[0].active,
336 | "conceptActive": docs[0].conceptActive,
337 | "fsn": docs[0].fsn,
338 | "module": docs[0].stringModule
339 | });
340 | callback(false, result);
341 | } else {
342 | var matchedDescriptions = docs.slice(0);
343 | if (filters.searchMode == "regex" || filters.searchMode == "partialMatching") {
344 | matchedDescriptions.sort(function(a, b) {
345 | if (a.term.length < b.term.length)
346 | return -1;
347 | if (a.term.length > b.term.length)
348 | return 1;
349 | return 0;
350 | });
351 | } else {
352 | matchedDescriptions.sort(function(a, b) {
353 | if (a.score > b.score)
354 | return -1;
355 | if (a.score < b.score)
356 | return 1;
357 | return 0;
358 | });
359 | }
360 | var count = 0;
361 | var conceptIds = [];
362 | matchedDescriptions.forEach(function(doc) {
363 | var refsetOk = false;
364 | if (doc.refsetIds) {
365 | doc.refsetIds.forEach(function(refset) {
366 | if (refset == filters.refsetFilter) {
367 | refsetOk = true;
368 | }
369 | });
370 | }
371 | if (filters.semanticFilter == "none" || (filters.semanticFilter == doc.semanticTag)) {
372 | if (filters.langFilter == "none" || (filters.langFilter == doc.languageCode)) {
373 | if (filters.moduleFilter == "none" || (filters.moduleFilter == doc.stringModule)) {
374 | if (filters.refsetFilter == "none" || refsetOk) {
375 | if (!filters["groupByConcept"] || conceptIds.indexOf(doc.conceptId) == -1) {
376 | conceptIds.push(doc.conceptId);
377 |
378 | if (count >= filters.skipTo && count < (filters.skipTo + filters.returnLimit)) {
379 | result.matches.push({
380 | "term": doc.term,
381 | "conceptId": doc.conceptId,
382 | "active": doc.active,
383 | "conceptActive": doc.conceptActive,
384 | "fsn": doc.fsn,
385 | "module": doc.stringModule,
386 | "definitionStatus": doc.definitionStatus
387 | });
388 | }
389 | if (result.filters.semTag.hasOwnProperty(doc.semanticTag)) {
390 | result.filters.semTag[doc.semanticTag] = result.filters.semTag[doc.semanticTag] + 1;
391 | } else {
392 | result.filters.semTag[doc.semanticTag] = 1;
393 | }
394 | if (result.filters.lang.hasOwnProperty(doc.languageCode)) {
395 | result.filters.lang[doc.languageCode] = result.filters.lang[doc.languageCode] + 1;
396 | } else {
397 | result.filters.lang[doc.languageCode] = 1;
398 | }
399 | if (result.filters.module.hasOwnProperty(doc.stringModule)) {
400 | result.filters.module[doc.stringModule] = result.filters.module[doc.stringModule] + 1;
401 | } else {
402 | result.filters.module[doc.stringModule] = 1;
403 | }
404 | if (doc.refsetIds) {
405 | doc.refsetIds.forEach(function(refset) {
406 | if (result.filters.refsetId.hasOwnProperty(refset)) {
407 | result.filters.refsetId[refset] = result.filters.refsetId[refset] + 1;
408 | } else {
409 | result.filters.refsetId[refset] = 1;
410 | }
411 | });
412 | }
413 | count = count + 1;
414 | }
415 | }
416 | }
417 | }
418 | }
419 | });
420 | result.details.total = count;
421 | callback(false, result);
422 |
423 | }
424 | } else {
425 | result.matches = [];
426 | result.details = { 'total': 0, 'skipTo': filters.skipTo, 'returnLimit': filters.returnLimit };
427 | callback(false, result);
428 | }
429 | };
430 | if (filters.searchMode == "regex" || filters.searchMode == "partialMatching") {
431 | //console.log("Entering part match search");
432 | getObject(dbP, collectionP + "tx", query, options, function(err, docs) {
433 | //console.log("Result: ", docs.length);
434 | processMatches(docs);
435 | });
436 | } else {
437 | getObject(dbP, collectionP + "tx", query, { score: { $meta: "textScore" } }, function(err, docs) {
438 | //console.log("Result: ", docs.length);
439 | processMatches(docs);
440 | });
441 | }
442 | // else {
443 | // performMongoDbRequest(dbP, function(db) {
444 | // console.log(collectionP);
445 | // var collection = db.collection(collectionP + 'tx');
446 | // collection.find(query, { score: { $meta: "textScore" } }).sort({ score: { $meta: "textScore" }}, function (err, cursor) {
447 | // if (err) {
448 | // console.log("Text index search error",err);
449 | // processMatches([]);
450 | // } else{
451 | // cursor.toArray(function(err, docs) {
452 | // console.log("docs found",docs.length);
453 | // processMatches(docs);
454 | // });
455 | // }
456 | // });
457 | // });
458 | // }
459 | };
460 |
461 | var getTime = function() {
462 | var currentdate = new Date();
463 | var datetime = "Last Sync: " + currentdate.getDate() + "/" +
464 | (currentdate.getMonth() + 1) + "/" +
465 | currentdate.getFullYear() + " @ " +
466 | currentdate.getHours() + ":" +
467 | currentdate.getMinutes() + ":" +
468 | currentdate.getSeconds();
469 | return datetime;
470 | };
471 |
472 | var getDefaultTermType = function(dbP, collectionP, callback) {
473 |
474 | var typeId = "900000000000003001";
475 | if (dbP == "en-edition") {
476 | //just return the FSN if it is the international edition
477 | callback(null, typeId);
478 | } else if (defaultTermTypes[dbP + "-" + collectionP]) {
479 | typeId = defaultTermTypes[dbP + "-" + collectionP];
480 | callback(null, typeId);
481 | } else {
482 | var options = {};
483 | options["fields"] = { "defaultTermType": 1 };
484 | var query = { databaseName: dbP, collectionName: collectionP.replace("v", "") };
485 |
486 | getObject("server", "resources", query, options, function(err, docs) {
487 | //console.log("Result: ", docs.length);
488 | if (err) callback(err);
489 | else {
490 | if (docs && docs.length > 0) {
491 | typeId = docs[0].defaultTermType;
492 | }
493 | defaultTermTypes[dbP + "-" + collectionP] = typeId;
494 | callback(null, typeId);
495 | }
496 | });
497 | }
498 | };
499 |
500 | module.exports.getObject = getObject;
501 | module.exports.getConcept = getConcept;
502 | module.exports.getDescriptions = getDescriptions;
503 | module.exports.getRelationShips = getRelationShips;
504 | module.exports.getParents = getParents;
505 | module.exports.getMembers = getMembers;
506 | module.exports.searchDescription = searchDescription;
507 | module.exports.getDefaultTermType = getDefaultTermType;
508 |
509 | var regExpEscape = function(s) {
510 | return String(s).replace(/([-()\[\]{}+?*.$\^|,:#= 0.0.0",
20 | "passport-local": ">= 0.0.0",
21 | "path": "^0.12.7",
22 | "pug": "^2.0.0-rc.1",
23 | "serve-favicon": "^2.4.1",
24 | "socket.io": "~1.7.3",
25 | "svg2png": "^4.1.1",
26 | "winston": "^2.2.0"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |