Skip to content

Commit

Permalink
Avoid using $unionWith as it isn't supported some places
Browse files Browse the repository at this point in the history
  • Loading branch information
manthey committed May 22, 2023
1 parent 40a5490 commit 1e30823
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 37 deletions.
79 changes: 42 additions & 37 deletions girder_annotation/girder_large_image_annotation/rest/annotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -582,20 +582,7 @@ def deleteItemAnnotations(self, item):

def getFolderAnnotations(self, id, recurse, user, limit=False, offset=False, sort=False,
sortDir=False, count=False):
recursivePipeline = [
{'$graphLookup': {
'from': 'folder',
'startWith': '$_id',
'connectFromField': '_id',
'connectToField': 'parentId',
'as': '__children'
}},
{'$unwind': {'path': '$__children'}},
{'$replaceRoot': {'newRoot': '$__children'}},
{'$unionWith': {
'coll': 'folder',
'pipeline': [{'$match': {'_id': ObjectId(id)}}]
}}] if recurse else []

accessPipeline = [
{'$match': {
'$or': [
Expand All @@ -612,36 +599,54 @@ def getFolderAnnotations(self, id, recurse, user, limit=False, offset=False, sor
]
}}
] if not user['admin'] else []
pipeline = [
{'$match': {'_id': 'none'}},
{'$unionWith': {
'coll': 'folder',
'pipeline': [{'$match': {'_id': ObjectId(id)}}] +
recursivePipeline +
[{'$lookup': {
'from': 'item',
'localField': '_id',
'foreignField': 'folderId',
'as': '__items'
}}, {'$lookup': {
'from': 'annotation',
'localField': '__items._id',
'foreignField': 'itemId',
'as': '__annotations'
}}, {'$unwind': '$__annotations'},
{'$replaceRoot': {'newRoot': '$__annotations'}},
{'$match': {'_active': {'$ne': False}}}
] + accessPipeline
recursivePipeline = [
{'$match': {'_id': ObjectId(id)}},
{'$facet': {
'documents1': [{'$match': {'_id': ObjectId(id)}}],
'documents2': [
{'$graphLookup': {
'from': 'folder',
'startWith': '$_id',
'connectFromField': '_id',
'connectToField': 'parentId',
'as': '__children'
}},
{'$unwind': {'path': '$__children'}},
{'$replaceRoot': {'newRoot': '$__children'}}
]
}},
]
{'$project': {'__children': {'$concatArrays': [
'$documents1', '$documents2'
]}}},
{'$unwind': {'path': '$__children'}},
{'$replaceRoot': {'newRoot': '$__children'}}
] if recurse else [{'$match': {'_id': ObjectId(id)}}]

pipeline = recursivePipeline + accessPipeline + [
{'$lookup': {
'from': 'item',
'localField': '_id',
'foreignField': 'folderId',
'as': '__items'
}},
{'$lookup': {
'from': 'annotation',
'localField': '__items._id',
'foreignField': 'itemId',
'as': '__annotations'
}},
{'$unwind': '$__annotations'},
{'$replaceRoot': {'newRoot': '$__annotations'}},
{'$match': {'_active': {'$ne': False}}}
] + accessPipeline

if count:
pipeline += [{'$count': 'count'}]
else:
pipeline = pipeline + [{'$sort': {sort: sortDir}}] if sort else pipeline
pipeline = pipeline + [{'$skip': offset}] if offset else pipeline
pipeline = pipeline + [{'$limit': limit}] if limit else pipeline

return Annotation().collection.aggregate(pipeline)
return Folder().collection.aggregate(pipeline)

@autoDescribeRoute(
Description('Check if the user owns any annotations for the items in a folder')
Expand Down
62 changes: 62 additions & 0 deletions girder_annotation/test_annotation/test_annotations_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
from girder_large_image_annotation.models.annotation import Annotation

from girder.constants import AccessType
from girder.models.collection import Collection
from girder.models.folder import Folder
from girder.models.item import Item
from girder.models.setting import Setting
except ImportError:
Expand Down Expand Up @@ -808,3 +810,63 @@ def testMetadataSearch(server, admin, fsAssetstore):
params={'q': 'key:key2 value', 'mode': 'li_annotation_metadata', 'types': '["item"]'})
assert utilities.respStatus(resp) == 200
assert len(resp.json['item']) == 0


@pytest.mark.usefixtures('unbindLargeImage', 'unbindAnnotation')
@pytest.mark.plugin('large_image_annotation')
def testFolderEndpoints(server, admin, user):
collection = Collection().createCollection(
'collection A', user)
colFolderA = Folder().createFolder(
collection, 'folder A', parentType='collection',
creator=user)
colFolderB = Folder().createFolder(
colFolderA, 'folder B', creator=user)
colFolderC = Folder().createFolder(
colFolderA, 'folder C', creator=admin, public=False)
colFolderC = Folder().setAccessList(colFolderC, access={'users': [], 'groups': []}, save=True)
itemA1 = Item().createItem('sample A1', user, colFolderA)
itemA2 = Item().createItem('sample A1', user, colFolderA)
itemB1 = Item().createItem('sample B1', user, colFolderB)
itemB2 = Item().createItem('sample B1', user, colFolderB)
itemC1 = Item().createItem('sample C1', admin, colFolderC)
itemC2 = Item().createItem('sample C1', admin, colFolderC)
Annotation().createAnnotation(itemA1, user, sampleAnnotation)
Annotation().createAnnotation(itemA1, admin, sampleAnnotation, public=False)
Annotation().createAnnotation(itemA2, user, sampleAnnotation)
Annotation().createAnnotation(itemB1, user, sampleAnnotation)
Annotation().createAnnotation(itemB1, admin, sampleAnnotation, public=False)
Annotation().createAnnotation(itemB2, user, sampleAnnotation)
Annotation().createAnnotation(itemC1, user, sampleAnnotation)
Annotation().createAnnotation(itemC1, admin, sampleAnnotation, public=False)
Annotation().createAnnotation(itemC2, user, sampleAnnotation)

resp = server.request(
path='/annotation/folder/' + str(colFolderA['_id']), user=admin,
params={'recurse': False})
assert utilities.respStatus(resp) == 200
assert len(resp.json) == 3

resp = server.request(
path='/annotation/folder/' + str(colFolderA['_id']), user=admin,
params={'recurse': True})
assert utilities.respStatus(resp) == 200
assert len(resp.json) == 9

resp = server.request(
path='/annotation/folder/' + str(colFolderA['_id']), user=user,
params={'recurse': False})
assert utilities.respStatus(resp) == 200
assert len(resp.json) == 3

resp = server.request(
path='/annotation/folder/' + str(colFolderA['_id']), user=user,
params={'recurse': True})
assert utilities.respStatus(resp) == 200
assert len(resp.json) == 6

resp = server.request(
path='/annotation/folder/' + str(colFolderC['_id']), user=user,
params={'recurse': True})
assert utilities.respStatus(resp) == 200
assert len(resp.json) == 0

0 comments on commit 1e30823

Please sign in to comment.