diff --git a/cubes/backends/mongo/browser.py b/cubes/backends/mongo/browser.py index 462d7d0e..75e9e25f 100644 --- a/cubes/backends/mongo/browser.py +++ b/cubes/backends/mongo/browser.py @@ -1,26 +1,28 @@ -from ...logging import get_logger -from ...errors import * -from ...browser import * -from ...computation import * -from ...statutils import calculators_for_aggregates, available_calculators -from cubes import statutils -from .mapper import MongoCollectionMapper -from .datesupport import MongoDateSupport -from .functions import get_aggregate_function, available_aggregate_functions -from .util import to_json_safe, collapse_record - import collections import copy -import pymongo -import bson +from datetime import datetime +from functools import partial +from itertools import groupby +import json import re +import bson +from cubes import statutils from dateutil.relativedelta import relativedelta -from datetime import datetime -from itertools import groupby -from functools import partial +import pymongo import pytz +from ...browser import * +from ...computation import * +from ...errors import * +from ...logging import get_logger +from ...statutils import calculators_for_aggregates, available_calculators +from .datesupport import MongoDateSupport +from .functions import get_aggregate_function, available_aggregate_functions +from .mapper import MongoCollectionMapper +from .util import to_json_safe, collapse_record +from pymongo.cursor import Cursor + tz_utc = pytz.timezone('UTC') @@ -202,7 +204,7 @@ def provide_members(self, cell, dimension, depth=None, hierarchy=None, attributes = [] for level in levels: - attributes += level.attributes + attributes += level.attributes drilldown = Drilldown([(dimension, hierarchy, levels[-1])], cell) @@ -392,14 +394,13 @@ def _date_transform(item, date_field): raise BrowserError("Measure cannot be in different database " "or collection than browser: %r" % phys) - aggregate_fn_pairs.append( ( escape_level(agg.ref()), sum ) ) - + aggregate_fn_pairs.append( ( escape_level(agg.ref()), function ) ) if phys.group: group = phys.group elif function: group_applicator = function["group_by"] - group = group_applicator(escape_level(agg.ref())) + group = group_applicator(escape_level(agg.measure or agg.ref())) else: raise ModelError("Neither function or mapping group specified " "for aggregate '%s' in cube '%s'" @@ -416,9 +417,10 @@ def _date_transform(item, date_field): pipeline = [] pipeline.append({ "$match": query_obj }) + pipeline.append({ "$group": group_obj }) if fields_obj: pipeline.append({ "$project": fields_obj }) - pipeline.append({ "$group": group_obj }) + if not timezone_shift_processing: if order: @@ -436,11 +438,15 @@ def _date_transform(item, date_field): pipeline.append({ "$limit": page_size }) result_items = [] - self.logger.debug("PIPELINE: %s", pipeline) - - results = self.data_store.aggregate(pipeline).get('result', []) + self.logger.debug("PIPELINE: %s", json.dumps(pipeline)) + + results = self.data_store.aggregate(pipeline) + # backwards compatibility + # since Pymongo 3.x CommandCursor is always returned + if isinstance(results, Cursor): + results = results.get('result', []) results = [date_transform(r) for r in results] - + if timezone_shift_processing: dategrouping = ['year', 'month', 'week', 'day', 'hour', 'minute'] datenormalize = ['year', 'month', 'week', 'dow', 'day', 'hour', 'minute'] diff --git a/cubes/backends/mongo/mapper.py b/cubes/backends/mongo/mapper.py index 821a1905..d7f25e6b 100644 --- a/cubes/backends/mongo/mapper.py +++ b/cubes/backends/mongo/mapper.py @@ -162,7 +162,8 @@ def __init__(self, cube, database, collection, mappings=None, **options): self.database = database self.collection = collection self.mappings = mappings or cube.mappings - + + def physical(self, attribute, locale=None): """Returns physical reference as tuple for `attribute`, which should be an instance of :class:`cubes.model.Attribute`. If there is no @@ -180,6 +181,7 @@ def physical(self, attribute, locale=None): # TODO: should default to non-localized reference if no mapping # was found? mapped_ref = self.cube.mappings.get(logical) + if mapped_ref: reference = coalesce_physical(self, mapped_ref) diff --git a/cubes/backends/mongo/store.py b/cubes/backends/mongo/store.py index 29bcefb6..f9af5408 100644 --- a/cubes/backends/mongo/store.py +++ b/cubes/backends/mongo/store.py @@ -9,4 +9,8 @@ def __init__(self, url, database=None, collection=None, **options): self.client = pymongo.MongoClient(url, read_preference=pymongo.read_preferences.ReadPreference.SECONDARY) self.database = database self.collection = collection + self.options = options + self.store_type = options['store_type'] + +