Skip to content
This repository was archived by the owner on Mar 2, 2026. It is now read-only.

feat: OR Query implementation#698

Merged
Mariatta merged 10 commits into
mainfrom
feat-or-query
Apr 3, 2023
Merged

feat: OR Query implementation#698
Mariatta merged 10 commits into
mainfrom
feat-or-query

Conversation

@Mariatta

@Mariatta Mariatta commented Mar 20, 2023

Copy link
Copy Markdown
Contributor

Introduce new Filter classes:

FieldFilter
And
Or

Add filter keyword arg to Query.where()
The positional arguments in Query.where() are now optional. UserWarning is now emitted when using where() without keyword args.

Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly:

  • Make sure to open an issue as a bug/issue before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea
  • Ensure the tests and linter pass
  • Code coverage does not decrease (if any source code was changed)
  • Appropriate docs were updated (if necessary)

Fixes #<issue_number_goes_here> 🦕

@Mariatta Mariatta requested review from a team March 20, 2023 22:39
@product-auto-label product-auto-label Bot added size: xl Pull request size is extra large. api: firestore Issues related to the googleapis/python-firestore API. labels Mar 20, 2023
@Mariatta Mariatta force-pushed the feat-or-query branch 2 times, most recently from 2cb52d3 to 1a7f8fd Compare March 21, 2023 00:48
@Mariatta Mariatta added the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Mar 21, 2023
@yoshi-kokoro yoshi-kokoro removed the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Mar 21, 2023
Comment thread google/cloud/firestore_v1/base_collection.py
Comment thread tests/system/test_system.py

@danieljbruce danieljbruce left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Just a few comments.

Comment thread google/cloud/firestore_v1/base_query.py Outdated
op=_enum_from_op_string(op_string),
value=_helpers.encode_value(value),

field_path_module.split_field_path(field_path) # raises

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was there meant to be more text in this comment?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this seems to have always been there since this code was added: https://github.com/googleapis/python-firestore/blame/main/google/cloud/firestore_v1/base_query.py#L246

Perhaps a leftover debugging info. I can remove it.

new_filters = self._field_filters + (filter_pb,)
new_filters += (filter_pb,)
elif isinstance(filter, BaseFilter):
new_filters += (filter._to_pb(),)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something we ran into with nodejs-datastore was that if we stored new variable types in this object that contained the old filter types then users who interacted with this array/list directly would see new filter types in this variable. If the user is then going to expect this variable to be an array of the old filter type then it could cause problems. Would the user ever interact with this variable directly out of the base query?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new_filters is a local variable only on the where function. User will not interact with it directly.

Comment thread google/cloud/firestore_v1/base_query.py
return _filter_pb(self._field_filters[0])
filter = self._field_filters[0]
if isinstance(filter, query.StructuredQuery.CompositeFilter):
return query.StructuredQuery.Filter(composite_filter=filter)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function returns a protobuf?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes.
It returns a new instance of the protobuf query.StructuredQuery.Filter()

@Mariatta Mariatta requested a review from kolea2 March 23, 2023 03:44
def query(query_docs):
collection, stored, allowed_vals = query_docs
query = collection.where("a", "==", 1)
query = collection.where(filter=FieldFilter("a", "==", 1))

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To the reviewers, this is an example of how the change in the where function.
It adds the keyword only arg filter, and you can see how it works before vs now.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The old behavior without the filter arg is still expected to work, correct? Are there any system tests that still validate the old behavior or is that unit test only now?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it still works, and I only have the unit test for it. I can add the system test too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added additional system tests here: eff9328

assert r.value == 2 # there are still only 2 docs


def test_query_with_and_composite_filter(query_docs):

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test cases below shows how to build composite filters using And and Or and how to pass them to the filter argument in where.

Comment thread google/cloud/firestore_v1/base_collection.py
Comment thread tests/system/test_system.py
Introduce new Filter classes:

FieldFilter
And
Or

Add "filter" keyword arg to "Query.where()"
The positional arguments in "Query.where()" are now optional.
UserWarning is now emitted when using "where()" without keyword args.
Comment thread google/cloud/firestore_v1/base_query.py
def query(query_docs):
collection, stored, allowed_vals = query_docs
query = collection.where("a", "==", 1)
query = collection.where(filter=FieldFilter("a", "==", 1))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The old behavior without the filter arg is still expected to work, correct? Are there any system tests that still validate the old behavior or is that unit test only now?

@Mariatta Mariatta merged commit 44dd5d6 into main Apr 3, 2023
@Mariatta Mariatta deleted the feat-or-query branch April 3, 2023 15:04
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

api: firestore Issues related to the googleapis/python-firestore API. size: xl Pull request size is extra large.

5 participants