openbel-api 0.5.1-java → 0.6.1-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/config/config.yml CHANGED
@@ -51,12 +51,10 @@ resource_search:
51
51
  # Set a secret used during session creation....
52
52
  session_secret: 'changeme'
53
53
 
54
- # User authentication using Auth0.
54
+ # User authentication via JWTs; see http://jwt.io/introduction/ for more
55
55
  auth:
56
+ # Controls whether the API requires authentication
56
57
  enabled: false
57
- redirect: 'https://openbel.auth0.com/authorize?response_type=code&scope=openid%20profile&client_id=K4oAPUaROjbWWTCoAhf0nKYfTGsZWbHE'
58
- default_connection: 'linkedin'
59
- domain: 'openbel.auth0.com'
60
- id: 'K4oAPUaROjbWWTCoAhf0nKYfTGsZWbHE'
61
- # secret: 'auth0 client secret here'
58
+ # Used by the auth middleware to decode and verify the JWT
59
+ #secret: 'JWT secret here'
62
60
 
@@ -15,6 +15,14 @@ module OpenBEL
15
15
  fail NotImplementedError, "#{__method__} is not implemented"
16
16
  end
17
17
 
18
+ def find_all_namespace_references
19
+ fail NotImplementedError, "#{__method__} is not implemented"
20
+ end
21
+
22
+ def find_all_annotation_references
23
+ fail NotImplementedError, "#{__method__} is not implemented"
24
+ end
25
+
18
26
  def count_evidence(filters = [])
19
27
  fail NotImplementedError, "#{__method__} is not implemented"
20
28
  end
@@ -72,11 +72,11 @@ module OpenBEL
72
72
  end
73
73
 
74
74
  def make_filter(category, name, value)
75
- MultiJson.dump({
75
+ {
76
76
  :category => category,
77
77
  :name => name,
78
- :value => value,
79
- })
78
+ :value => value
79
+ }
80
80
  end
81
81
  end
82
82
  end
@@ -1,4 +1,5 @@
1
1
  require 'bel'
2
+ require 'bel/evidence_model/util'
2
3
  require 'mongo'
3
4
  require_relative 'api'
4
5
  require_relative 'mongo_facet'
@@ -11,10 +12,15 @@ module OpenBEL
11
12
  include Mongo
12
13
 
13
14
  def initialize(options = {})
14
- host = options[:host]
15
- port = options[:port]
16
- db = options[:database]
17
- @db = MongoClient.new(host, port).db(db)
15
+ host = options[:host]
16
+ port = options[:port]
17
+ db = options[:database]
18
+ @db = MongoClient.new(
19
+ host,
20
+ port,
21
+ :op_timeout => nil,
22
+ :pool_size => 30
23
+ ).db(db)
18
24
 
19
25
  # Authenticate user if provided.
20
26
  username = options[:username]
@@ -25,15 +31,10 @@ module OpenBEL
25
31
  end
26
32
 
27
33
  @collection = @db[:evidence]
28
- @collection.ensure_index(
29
- {:"bel_statement" => Mongo::ASCENDING },
30
- :background => true
31
- )
32
- @collection.ensure_index(
33
- {:"$**" => Mongo::TEXT },
34
- :background => true
35
- )
36
34
  @evidence_facets = EvidenceFacets.new(options)
35
+
36
+ # ensure all indexes are created and maintained
37
+ ensure_all_indexes
37
38
  end
38
39
 
39
40
  def create_evidence(evidence)
@@ -55,29 +56,16 @@ module OpenBEL
55
56
  @collection.find_one(to_id(value))
56
57
  end
57
58
 
58
- def find_evidence(filters = [], offset = 0, length = 0, facet = false)
59
- query_hash = to_query(filters)
60
- query_opts = query_options(
61
- query_hash,
62
- :skip => offset,
63
- :limit => length,
64
- :sort => [
65
- [:bel_statement, :asc]
66
- ]
67
- )
68
-
69
- results = {
70
- :cursor => @collection.find(query_hash, query_opts)
71
- }
72
- if facet
73
- facets_doc = @evidence_facets.find_facets(query_hash, filters)
74
- results[:facets] = facets_doc["facets"]
59
+ def find_evidence(filters = [], offset = 0, length = 0, facet = false, facet_value_limit = -1)
60
+ if includes_fts_search?(filters)
61
+ text_search = get_fts_search(filters)
62
+ evidence_aggregate(text_search, filters, offset, length, facet, facet_value_limit)
63
+ else
64
+ evidence_query(filters, offset, length, facet, facet_value_limit)
75
65
  end
76
-
77
- results
78
66
  end
79
67
 
80
- def find_dataset_evidence(dataset, filters = [], offset = 0, length = 0, facet = false)
68
+ def find_dataset_evidence(dataset, filters = [], offset = 0, length = 0, facet = false, facet_value_limit = -1)
81
69
  query_hash = to_query(filters)
82
70
  query_hash[:$and] ||= []
83
71
  query_hash[:$and].unshift({
@@ -97,13 +85,124 @@ module OpenBEL
97
85
  :cursor => @collection.find(query_hash, query_opts)
98
86
  }
99
87
  if facet
100
- facets_doc = @evidence_facets.find_facets(query_hash, filters)
101
- results[:facets] = facets_doc["facets"]
88
+ facets_cursor = @evidence_facets.find_facets(query_hash, filters, facet_value_limit)
89
+ results[:facets] = facets_cursor.to_a
102
90
  end
103
91
 
104
92
  results
105
93
  end
106
94
 
95
+ def find_all_namespace_references
96
+ references = @collection.aggregate(
97
+ [
98
+ {
99
+ :$project => {
100
+ "references.namespaces" => 1
101
+ }
102
+ },
103
+ {
104
+ :$unwind => "$references.namespaces"
105
+ },
106
+ {
107
+ :$project => {
108
+ keyword: "$references.namespaces.keyword",
109
+ uri: "$references.namespaces.uri"
110
+ }
111
+ },
112
+ {
113
+ :$group => {
114
+ _id: "$keyword", uri: {
115
+ :$addToSet => "$uri"
116
+ }
117
+ }
118
+ },
119
+ {
120
+ :$unwind => "$uri"
121
+ },
122
+ {
123
+ :$project => {
124
+ keyword: "$_id", uri: "$uri", _id: 0
125
+ }
126
+ }
127
+ ],
128
+ {
129
+ allowDiskUse: true,
130
+ cursor: {}
131
+ }
132
+ )
133
+
134
+ union = []
135
+ remap = {}
136
+ references.each do |obj|
137
+ obj = obj.to_h
138
+ obj[:keyword] = obj.delete("keyword")
139
+ obj[:uri] = obj.delete("uri")
140
+ union, new_remap = BEL::Model.union_namespace_references(union, [obj], 'incr')
141
+ remap.merge!(new_remap)
142
+ end
143
+
144
+ remap
145
+ end
146
+
147
+ def find_all_annotation_references
148
+ references = @collection.aggregate(
149
+ [
150
+ {
151
+ :$project => {"references.annotations" => 1}
152
+ },
153
+ {
154
+ :$unwind => "$references.annotations"
155
+ },
156
+ {
157
+ :$project => {
158
+ keyword: "$references.annotations.keyword",
159
+ type: "$references.annotations.type",
160
+ domain: "$references.annotations.domain"
161
+ }
162
+ },
163
+ {
164
+ :$group => {
165
+ _id: "$keyword",
166
+ type: {
167
+ :$addToSet => "$type"
168
+ },
169
+ domain: {
170
+ :$addToSet => "$domain"
171
+ }
172
+ }
173
+ },
174
+ {
175
+ :$unwind => "$type"
176
+ },
177
+ {
178
+ :$unwind => "$domain"
179
+ },
180
+ {
181
+ :$project => {
182
+ keyword: "$_id", type: "$type", domain: "$domain", _id: 0
183
+ }
184
+ }
185
+ ],
186
+ {
187
+ allowDiskUse: true,
188
+ cursor: {}
189
+ }
190
+ )
191
+
192
+ union = []
193
+ remap = {}
194
+ references.each do |obj|
195
+ obj = obj.to_h
196
+ obj[:keyword] = obj.delete("keyword")
197
+ obj[:type] = obj.delete("type")
198
+ obj[:domain] = obj.delete("domain")
199
+ union, new_remap = BEL::Model.union_annotation_references(union, [obj], 'incr')
200
+ remap.merge!(new_remap)
201
+ end
202
+
203
+ remap
204
+ end
205
+
107
206
  def count_evidence(filters = [])
108
207
  query_hash = to_query(filters)
109
208
  @collection.count(:query => query_hash)
@@ -123,16 +222,16 @@ module OpenBEL
123
222
  nil
124
223
  end
125
224
 
126
- def delete_dataset(identifier)
127
- @collection.ensure_index(
128
- {:"_dataset" => Mongo::ASCENDING },
129
- :background => true
130
- )
225
+ def delete_facets
226
+ @evidence_facets.delete_all_facets
227
+ end
131
228
 
229
+ def delete_dataset(identifier)
132
230
  @collection.remove(
133
231
  { :"_dataset" => identifier },
134
232
  :j => true
135
233
  )
234
+ @evidence_facets.delete_all_facets
136
235
  end
137
236
 
138
237
  def delete_evidence(value)
@@ -173,8 +272,170 @@ module OpenBEL
173
272
  )
174
273
  end
175
274
 
275
+ def ensure_all_indexes
276
+ @collection.ensure_index(
277
+ { :bel_statement => Mongo::ASCENDING },
278
+ :background => true
279
+ )
280
+ @collection.ensure_index(
281
+ { :"$**" => Mongo::TEXT },
282
+ :background => true
283
+ )
284
+ @collection.ensure_index(
285
+ { :_dataset => Mongo::ASCENDING },
286
+ :background => true
287
+ )
288
+ @collection.ensure_index(
289
+ { :"experiment_context.name" => Mongo::ASCENDING },
290
+ :background => true
291
+ )
292
+ @collection.ensure_index(
293
+ { :"metadata.name" => Mongo::ASCENDING },
294
+ :background => true
295
+ )
296
+ end
297
+
176
298
  private
177
299
 
300
+ def evidence_query(filters = [], offset = 0, length = 0, facet = false, facet_value_limit = -1)
301
+ query_hash = to_query(filters)
302
+ query_opts = query_options(
303
+ query_hash,
304
+ :skip => offset,
305
+ :limit => length,
306
+ :sort => [
307
+ [:bel_statement, :asc]
308
+ ]
309
+ )
310
+
311
+ results = {
312
+ :cursor => @collection.find(query_hash, query_opts)
313
+ }
314
+ if facet
315
+ facets_cursor = @evidence_facets.find_facets(query_hash, filters, facet_value_limit)
316
+ results[:facets] = facets_cursor.to_a
317
+ end
318
+
319
+ results
320
+ end
321
+
322
+ def evidence_aggregate(text_search, filters = [], offset = 0, length = 0, facet = false, facet_value_limit = -1)
323
+ match_filters = filters.select { |filter|
324
+ filter['category'] != 'fts'
325
+ }
326
+ match = build_filter_query(match_filters)
327
+ match[:$and].unshift({
328
+ :$text => {
329
+ :$search => text_search
330
+ }
331
+ })
332
+
333
+ pipeline = [
334
+ {
335
+ :$match => match
336
+ },
337
+ {
338
+ :$project => {
339
+ :_id => 1,
340
+ :bel_statement => 1,
341
+ :score => {
342
+ :$meta => 'textScore'
343
+ }
344
+ }
345
+ },
346
+ {
347
+ :$sort => {
348
+ :score => {
349
+ :$meta => 'textScore'
350
+ },
351
+ :bel_statement => 1
352
+ }
353
+ }
354
+ ]
355
+
356
+ if offset > 0
357
+ pipeline << {
358
+ :$skip => offset
359
+ }
360
+ end
361
+
362
+ if length > 0
363
+ pipeline << {
364
+ :$limit => length
365
+ }
366
+ end
367
+
368
+ fts_cursor = @collection.aggregate(pipeline, {
369
+ :allowDiskUse => true,
370
+ :cursor => {
371
+ :batchSize => 0
372
+ }
373
+ })
374
+ _ids = fts_cursor.map { |doc| doc['_id'] }
375
+
376
+ facets =
377
+ if facet
378
+ query_hash = to_query(filters)
379
+ facets_cursor = @evidence_facets.find_facets(query_hash, filters, facet_value_limit)
380
+ facets_cursor.to_a
381
+ else
382
+ nil
383
+ end
384
+
385
+ {
386
+ :cursor => @collection.find({:_id => {:$in => _ids}}),
387
+ :facets => facets
388
+ }
389
+ end
390
+
391
+ def includes_fts_search?(filters)
392
+ filters.any? { |filter|
393
+ filter['category'] == 'fts' && filter['name'] == 'search'
394
+ }
395
+ end
396
+
397
+ def get_fts_search(filters)
398
+ fts_filter = filters.find { |filter|
399
+ filter['category'] == 'fts' && filter['name'] == 'search'
400
+ }
401
+ fts_filter.fetch('value', '')
402
+ end
403
+
404
+ def build_filter_query(filters = [])
405
+ {
406
+ :$and => filters.map { |filter|
407
+ category = filter['category']
408
+ name = filter['name']
409
+ value = filter['value']
410
+
411
+ case category
412
+ when 'experiment_context'
413
+ {
414
+ :experiment_context => {
415
+ :$elemMatch => {
416
+ :name => name.to_s,
417
+ :value => value.to_s
418
+ }
419
+ }
420
+ }
421
+ when 'metadata'
422
+ {
423
+ :metadata => {
424
+ :$elemMatch => {
425
+ :name => name.to_s,
426
+ :value => value.to_s
427
+ }
428
+ }
429
+ }
430
+ else
431
+ {
432
+ "#{filter['category']}.#{filter['name']}" => filter['value'].to_s
433
+ }
434
+ end
435
+ }
436
+ }
437
+ end
438
+
178
439
  def to_query(filters = [])
179
440
  if !filters || filters.empty?
180
441
  return {}
@@ -238,13 +499,12 @@ module OpenBEL
238
499
  end
239
500
 
240
501
  def remove_evidence_facets(_id)
241
- evidence = @collection.find_one(_id, {
242
- :fields => [ 'facets' ]
502
+ doc = @collection.find_one(_id, {
503
+ :fields => {:_id => 0, :facets => 1}
243
504
  })
244
505
 
245
- if evidence && evidence.has_key?('facets')
246
- @evidence_facets.remove_facets_by_filters(evidence['facets'])
247
- @evidence_facets.remove_facets_by_filters
506
+ if doc && doc.has_key?('facets')
507
+ @evidence_facets.delete_facets(doc['facets'])
248
508
  end
249
509
  end
250
510
  end