New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aggregation query parameter does not replace keys in the lists #1025

Closed
yjcrocks opened this Issue Jun 10, 2017 · 7 comments

Comments

Projects
None yet
5 participants
@yjcrocks

yjcrocks commented Jun 10, 2017

I was working on an aggregation endpoint:

things_recommended = {
    'url': 'things/recommended/',
    'datasource': {
        'source': 'things',
        'aggregation': {
            'pipeline': [
                {"$match": {"$or": [{"family": "$family_id"}, {"is_shared": True}]}},
                {"$addFields": {
                    "recommended_for_me":
                    {"$setIsSubset":[["$user_id"], "$recommended_to"]}
                }},
                {"$sort": SON([("recommended_for_me", -1), ("happened", -1)])}
            ]
        }
    }
}

However, I found that $family_id and $user_id are not getting replaced since the code only covers the case of a pure dictionary without lists.

See:

if isinstance(st_value, dict):

I'm new to Eve, so I'm not sure that what I found worth an error report. Though it took me quite a time to debug.

Best regards,
Youngjae

PS, Eve is AWESOME.

@yjcrocks yjcrocks changed the title from Aggregation query parameter does not replace values in the list to Aggregation query parameter does not replace keys in the lists Jun 10, 2017

@yjcrocks

This comment has been minimized.

yjcrocks commented Jun 10, 2017

I solved the issue like this:

def parse_aggregation_stage(d, key, value):
        if isinstance(d, dict):
            for st_key, st_value in d.items():
                if isinstance(st_value, dict) or isinstance(st_value, list):
                    parse_aggregation_stage(st_value, key, value)
                if key == st_value:
                    d[st_key] = value
        if isinstance(d, list):
            for st_idx, st_value in enumerate(d):
                if isinstance(st_value, dict) or isinstance(st_value, list):
                    parse_aggregation_stage(st_value, key, value)
                if key == st_value:
                    d[st_idx] = value
@Amedeo91

This comment has been minimized.

Amedeo91 commented Jun 29, 2017

Did you do the PR?

@zhangtemplar

This comment has been minimized.

Contributor

zhangtemplar commented Aug 7, 2017

+1 this resolves my problem.

@zhangtemplar

This comment has been minimized.

Contributor

zhangtemplar commented Aug 8, 2017

Hi, there is a work around for this problem.

For example, if you have the following end points, which doesn't work as array is not yet supported:

things_recommended = {
    'url': 'things/recommended/',
    'datasource': {
        'source': 'things',
        'aggregation': {
            'pipeline': [
                {"$match": {"$or": [{"family": "$family_id"}, {"is_shared": True}]}},
            ]
        }
    }
}

However, you can overcome this problem by defining the endpoint like:

things_recommended = {
    'url': 'things/recommended/',
    'datasource': {
        'source': 'things',
        'aggregation': {
            'pipeline': [
                {"$match": "$where"},
            ]
        }
    }
}

The query url is like

some_url/things/recommended?aggregate={"$where": {"$or": [{"family": "$family_id"}, {"is_shared": True}]}}

Note you need to use encoderUrlComponent and JSON.stringfy to escape the characters in this url.

I have tested on my computer and it works.

@aarobc

This comment has been minimized.

aarobc commented Sep 4, 2017

I'm having a similar problem and haven't had much luck. Is the unterminated quote in your example on {"$match": "$where$}, intentional?

@zhangtemplar

This comment has been minimized.

Contributor

zhangtemplar commented Sep 5, 2017

@aarobc sorry, it should be a typo and the correct case would be {"$match": "$where"}

@nicolaiarocci

This comment has been minimized.

Member

nicolaiarocci commented Nov 4, 2017

Solved by #1058

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment