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.
- checksums.yaml +4 -4
- data/.gemspec +14 -6
- data/CHANGELOG.md +32 -0
- data/README.md +2 -2
- data/VERSION +1 -1
- data/app/openbel/api/config.rb +12 -0
- data/app/openbel/api/helpers/base.rb +17 -0
- data/app/openbel/api/helpers/evidence.rb +74 -0
- data/app/openbel/api/helpers/filters.rb +94 -0
- data/app/openbel/api/helpers/translators.rb +73 -0
- data/app/openbel/api/resources/evidence_transform.rb +1 -13
- data/app/openbel/api/routes/authenticate.rb +0 -92
- data/app/openbel/api/routes/base.rb +19 -5
- data/app/openbel/api/routes/datasets.rb +65 -151
- data/app/openbel/api/routes/evidence.rb +10 -95
- data/config/config.yml +4 -6
- data/lib/openbel/api/evidence/api.rb +8 -0
- data/lib/openbel/api/evidence/facet_filter.rb +3 -3
- data/lib/openbel/api/evidence/mongo.rb +304 -44
- data/lib/openbel/api/evidence/mongo_facet.rb +173 -66
- metadata +112 -26
- data/config/async_evidence.rb +0 -12
- data/config/async_jena.rb +0 -14
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
|
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
|
-
|
58
|
-
|
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
|
@@ -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
|
15
|
-
port
|
16
|
-
db
|
17
|
-
@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
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
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
|
-
|
101
|
-
results[: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
|
127
|
-
@
|
128
|
-
|
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
|
-
|
242
|
-
:fields =>
|
502
|
+
doc = @collection.find_one(_id, {
|
503
|
+
:fields => {:_id => 0, :facets => 1}
|
243
504
|
})
|
244
505
|
|
245
|
-
if
|
246
|
-
@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
|