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
Add mongo length operator functionality with length aliases #222
Conversation
Codecov Report
@@ Coverage Diff @@
## master #222 +/- ##
==========================================
+ Coverage 87.11% 87.53% +0.42%
==========================================
Files 43 45 +2
Lines 1862 1941 +79
==========================================
+ Hits 1622 1699 +77
- Misses 240 242 +2
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting implementation. Very nice. I have some minor suggested changes.
Are you happy with the proposed structure then, or would you prefer it in |
I've just realised another feature that could use this approach, filtering on relationships. I've implemented this on my branch |
0d03180
to
b0de4ad
Compare
Yeah. I see what you mean. I don't know. I would probably prefer it in the collection class, however, it may also be useful for other backends? But I'm not entirely sure. |
I've completely rewritten this process to make it more general across different post-processing operations, but think the actual descent into the query is going to very mongo specific. As it is, we can definitely lift this out and put it into the collection class. |
bdc1205
to
b4f528f
Compare
2e034a1
to
51cf0cd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
I'll give @CasperWA a while (~week) to look before merging this. |
280a1e7
to
8d176a8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking awesome, thanks @ml-evs!
Only a few minor comments.
I am truly enjoying that the Collection has been trimmed a bit, and the Transformer can handle all transformation-related aspects of the query, instead of having a bit here and there.
|
||
def test_unaliased_length_operator(self): | ||
transformer = MongoTransformer() | ||
parser = LarkParser(version=self.version, variant=self.variant) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here as the previous comment. And even the transformer doesn't need to be redefined, since it should be t
from line 16?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The transformer in these tests needs to take a mapper as an argument, so the same one can't be reused. This means the parser also can't be reused (its out of scope in the methods, we only expose the transform method which is tied to the transformer).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you see the def setUp()
, which runs just prior of this test method, why wouldn't that suffice for the tests in this method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The transformer in these tests needs to take a mapper as an argument (...)
But in this exact test method, the transformer doesn't take a mapper as an argument? I am confused :( I see that it makes sense to instantiate a new transformer for the other test methods you added, but not for this one.
And how is the parser out of scope? It doesn't depend on the transformer as far as I know? Or? :|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The transformer in these tests needs to take a mapper as an argument, so the same one can't be reused. This means the parser also can't be reused (its out of scope in the methods, we only expose the transform method which is tied to the transformer).
AAAHHH I see the whole problem now - sorry!! Yeah, we set both the parser and transformer in the setUp
method, but only keep the transform
in the instance..... right, right, right.
So would it make sense then to expose the instantiated transformer and parser?
Or maybe create a transform_mapped
lambda function?
Also, I think the setUp()
should be setUpClass()
, right? Is there a need to instantiate this before each test method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replied to the wrong comment initially, sorry! I've amended my commit with your suggestion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So would it make sense then to expose the instantiated transformer and parser?
The other two new tests can't use this anyway, so I think it's now fine as is
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool. I'll stop poking at this.
(although, just tested locally changing this to setUpClass()
, and it works only if one then makes transform
an actual separate class method, and consequently "saves" the instantiated parser and transformer as class attributes.)
Co-authored-by: Casper Welzel Andersen <CasperWA@users.noreply.github.com>
7884dea
to
9be0f61
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
C'est magnifique !
Thanks for the additions and updates. I think this quite an elegant solution in the end 👍
Please merge at your leisure.
This PR is a WIP/proof of concept for the introduction of "length aliases" to attempt to fix the issues in #86.
This PR adds a post-processing function to the
MongoTransformer
which recursively descends into the transformed filter and tries to change any{"x": {"$size": 3}}
queries with the value of a value of corresponding aliased field, e.g.elements->nelements
. The benefits are minimal when just performingLENGTH = value
queries (as $size can do this rapidly anyway), but this will greatly speed upLENGTH > 3
queries, which mongo does not support directly (see #86 discussion). Length operator queries that do not have a defined length alias will now fallback to using the existence test approach, i.e.LENGTH > 3
becomes "does element 4 exist?".Extra changes needed to support this:
entry_collections
into submodules (entry_collections.entry_collections
andentry_collections.mongo
).LENGTH_ALIASES
attribute to mappers and config.PROVIDER_FIELDS
to mapper to mirror other aliases.$exists
for fallback length operationsStructureMapper
, but will be ignored unless aTransformer
makes use of them.