Skip to content
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
Closed

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

yjcrocks opened this issue Jun 10, 2017 · 7 comments

Comments

@yjcrocks
Copy link

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 Aggregation query parameter does not replace values in the list Aggregation query parameter does not replace keys in the lists Jun 10, 2017
@yjcrocks
Copy link
Author

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
Copy link

Did you do the PR?

@zhangtemplar
Copy link
Contributor

+1 this resolves my problem.

@zhangtemplar
Copy link
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
Copy link

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
Copy link
Contributor

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

@nicolaiarocci
Copy link
Member

Solved by #1058

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants