|
@@ -1,4 +1,8 @@
|
1
|
1
|
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+import bson
|
|
4
|
+from bson.son import SON
|
|
5
|
+from collections import OrderedDict
|
2
|
6
|
import pymongo
|
3
|
7
|
from pymongo import MongoClient
|
4
|
8
|
from pymongo.errors import BulkWriteError
|
|
@@ -64,12 +68,11 @@ class MongoDbDataSource(GenericDataSource):
|
64
|
68
|
# @param filters list : List of filters
|
65
|
69
|
# @param rel_filters list : List of relational filters
|
66
|
70
|
# @param order list : List of column to order. ex: order = [('title', 'ASC'),]
|
67
|
|
- # @param group list : List of tupple representing the column to group together. ex: group = [('title', 'ASC'),]
|
|
71
|
+ # @param group list : List of tupple representing the column used as "group by" fields. ex: group = [('title', 'ASC'),]
|
68
|
72
|
# @param limit int : Number of records to be returned
|
69
|
73
|
# @param offset int: used with limit to choose the start record
|
70
|
74
|
# @param instanciate bool : If true, the records are returned as instances, else they are returned as dict
|
71
|
75
|
# @return list
|
72
|
|
- # @todo Implement the grouping
|
73
|
76
|
# @todo Implement the relations
|
74
|
77
|
def select(self, target_cls, field_list, filters, rel_filters=None, order=None, group=None, limit=None, offset=0,
|
75
|
78
|
instanciate=True):
|
|
@@ -79,13 +82,41 @@ class MongoDbDataSource(GenericDataSource):
|
79
|
82
|
query_result_ordering = utils.parse_query_order(order) if order is not None else None
|
80
|
83
|
results_field_list = None if len(field_list) == 0 else field_list
|
81
|
84
|
limit = limit if limit is not None else 0
|
82
|
|
- cursor = collection.find(
|
83
|
|
- filter=query_filters,
|
84
|
|
- projection=results_field_list,
|
85
|
|
- skip=offset,
|
86
|
|
- limit=limit,
|
87
|
|
- sort=query_result_ordering
|
88
|
|
- )
|
|
85
|
+
|
|
86
|
+ if group is None:
|
|
87
|
+ cursor = collection.find(
|
|
88
|
+ filter=query_filters,
|
|
89
|
+ projection=results_field_list,
|
|
90
|
+ skip=offset,
|
|
91
|
+ limit=limit,
|
|
92
|
+ sort=query_result_ordering
|
|
93
|
+ )
|
|
94
|
+ else:
|
|
95
|
+ pipeline = list()
|
|
96
|
+ unwinding_list = list()
|
|
97
|
+ grouping_dict = OrderedDict()
|
|
98
|
+ sorting_list = list()
|
|
99
|
+ for group_param in group:
|
|
100
|
+ field_name = group_param[0]
|
|
101
|
+ field_sort_option = group_param[1]
|
|
102
|
+ sort_option = utils.MONGODB_SORT_OPERATORS_MAP[field_sort_option]
|
|
103
|
+ unwinding_list.append({'$unwind': '$%s' % field_name})
|
|
104
|
+ grouping_dict[field_name] = '$%s' % field_name
|
|
105
|
+ sorting_list.append((field_name, sort_option))
|
|
106
|
+
|
|
107
|
+ sorting_list.extends(query_result_ordering)
|
|
108
|
+
|
|
109
|
+ pipeline.append({'$match': query_filters})
|
|
110
|
+ if results_field_list is not None:
|
|
111
|
+ pipeline.append({'$project': SON([{field_name: 1} for field_name in field_list])})
|
|
112
|
+ pipeline.extend(unwinding_list)
|
|
113
|
+ pipeline.append({'$group': grouping_dict})
|
|
114
|
+ pipeline.extend({'$sort': SON(sorting_list)})
|
|
115
|
+ if offset > 0:
|
|
116
|
+ pipeline.append({'$skip': offset})
|
|
117
|
+ if limit is not None:
|
|
118
|
+ pipeline.append({'$limit': limit})
|
|
119
|
+
|
89
|
120
|
results = list()
|
90
|
121
|
for document in cursor:
|
91
|
122
|
results.append(document)
|