Skip to content

Commit

Permalink
feat(firestore): Add IN and ARRAY_CONTAINS_ANY query operators
Browse files Browse the repository at this point in the history
closes: #4745
pr: #4823
  • Loading branch information
quartzmo committed Feb 24, 2020
1 parent be9f1a8 commit 5a14fd6
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 19 deletions.
18 changes: 17 additions & 1 deletion google-cloud-firestore/acceptance/firestore/query_test.rb
Expand Up @@ -39,14 +39,30 @@
result_snp[:foo].must_equal "bar"
end

it "has where method with array_contains " do
it "has where method with array_contains" do
rand_query_col = firestore.col "#{root_path}/query/#{SecureRandom.hex(4)}"
rand_query_col.add({foo: ["bar", "baz", "bif"]})

result_snp = rand_query_col.where(:foo, :array_contains, :bif).get.first
result_snp[:foo].must_equal ["bar", "baz", "bif"]
end

it "has where method with in" do
rand_query_col = firestore.col "#{root_path}/query/#{SecureRandom.hex(4)}"
rand_query_col.add({foo: "bar"})

result_snp = rand_query_col.where(:foo, :in, ["bar", "baz", "bif"]).get.first
result_snp[:foo].must_equal "bar"
end

it "has where method with array_contains_any" do
rand_query_col = firestore.col "#{root_path}/query/#{SecureRandom.hex(4)}"
rand_query_col.add({foo: ["bar", "baz", "bif"]})

result_snp = rand_query_col.where(:foo, :array_contains_any, [:bif, :out]).get.first
result_snp[:foo].must_equal ["bar", "baz", "bif"]
end

it "supports NaN" do
rand_query_col = firestore.col "#{root_path}/query/#{SecureRandom.hex(4)}"
doc_ref = rand_query_col.add({foo: Float::NAN})
Expand Down
39 changes: 21 additions & 18 deletions google-cloud-firestore/lib/google/cloud/firestore/query.rb
Expand Up @@ -888,24 +888,27 @@ def self.start query, parent_path, client
##
# @private
FILTER_OPS = {
"<" => :LESS_THAN,
"lt" => :LESS_THAN,
"<=" => :LESS_THAN_OR_EQUAL,
"lte" => :LESS_THAN_OR_EQUAL,
">" => :GREATER_THAN,
"gt" => :GREATER_THAN,
">=" => :GREATER_THAN_OR_EQUAL,
"gte" => :GREATER_THAN_OR_EQUAL,
"=" => :EQUAL,
"==" => :EQUAL,
"eq" => :EQUAL,
"eql" => :EQUAL,
"is" => :EQUAL,
"array_contains" => :ARRAY_CONTAINS,
"array-contains" => :ARRAY_CONTAINS,
"include" => :ARRAY_CONTAINS,
"include?" => :ARRAY_CONTAINS,
"has" => :ARRAY_CONTAINS
"<" => :LESS_THAN,
"lt" => :LESS_THAN,
"<=" => :LESS_THAN_OR_EQUAL,
"lte" => :LESS_THAN_OR_EQUAL,
">" => :GREATER_THAN,
"gt" => :GREATER_THAN,
">=" => :GREATER_THAN_OR_EQUAL,
"gte" => :GREATER_THAN_OR_EQUAL,
"=" => :EQUAL,
"==" => :EQUAL,
"eq" => :EQUAL,
"eql" => :EQUAL,
"is" => :EQUAL,
"array_contains" => :ARRAY_CONTAINS,
"array-contains" => :ARRAY_CONTAINS,
"include" => :ARRAY_CONTAINS,
"include?" => :ARRAY_CONTAINS,
"has" => :ARRAY_CONTAINS,
"in" => :IN,
"array_contains_any" => :ARRAY_CONTAINS_ANY,
"array-contains-any" => :ARRAY_CONTAINS_ANY
}.freeze
##
# @private
Expand Down
@@ -0,0 +1,78 @@
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require "helper"

describe Google::Cloud::Firestore::Query, :where, :array_contains_any, :mock_firestore do
let(:query) { Google::Cloud::Firestore::Query.start nil, "#{firestore.path}/documents", firestore }

it "using array-contains-any" do
expected_query = Google::Firestore::V1::StructuredQuery.new(
where: Google::Firestore::V1::StructuredQuery::Filter.new(
field_filter: Google::Firestore::V1::StructuredQuery::FieldFilter.new(
field: Google::Firestore::V1::StructuredQuery::FieldReference.new(field_path: "foo"),
op: :ARRAY_CONTAINS_ANY,
value: Google::Firestore::V1::Value.new(integer_value: 42)
)
)
)

generated_query = query.where(:foo, "array-contains-any", 42).query
generated_query.must_equal expected_query
end

it "using array_contains_any" do
expected_query = Google::Firestore::V1::StructuredQuery.new(
where: Google::Firestore::V1::StructuredQuery::Filter.new(
field_filter: Google::Firestore::V1::StructuredQuery::FieldFilter.new(
field: Google::Firestore::V1::StructuredQuery::FieldReference.new(field_path: "foo"),
op: :ARRAY_CONTAINS_ANY,
value: Google::Firestore::V1::Value.new(integer_value: 42)
)
)
)

generated_query = query.where(:foo, :array_contains_any, 42).query
generated_query.must_equal expected_query
end

it "with multiple values" do
expected_query = Google::Firestore::V1::StructuredQuery.new(
where: Google::Firestore::V1::StructuredQuery::Filter.new(
composite_filter: Google::Firestore::V1::StructuredQuery::CompositeFilter.new(
op: :AND,
filters: [
Google::Firestore::V1::StructuredQuery::Filter.new(
field_filter: Google::Firestore::V1::StructuredQuery::FieldFilter.new(
field: Google::Firestore::V1::StructuredQuery::FieldReference.new(field_path: "foo"),
op: :ARRAY_CONTAINS_ANY,
value: Google::Firestore::V1::Value.new(integer_value: 42)
)
),
Google::Firestore::V1::StructuredQuery::Filter.new(
field_filter: Google::Firestore::V1::StructuredQuery::FieldFilter.new(
field: Google::Firestore::V1::StructuredQuery::FieldReference.new(field_path: "foo"),
op: :ARRAY_CONTAINS_ANY,
value: Google::Firestore::V1::Value.new(integer_value: 43)
)
)
]
)
)
)

generated_query = query.where(:foo, :array_contains_any, 42).where(:foo, :array_contains_any, 43).query
generated_query.must_equal expected_query
end
end
@@ -0,0 +1,84 @@
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require "helper"

describe Google::Cloud::Firestore::Query, :where, :array_contains_any, :mock_firestore do
let(:query) { Google::Cloud::Firestore::Query.start nil, "#{firestore.path}/documents", firestore }

it "using in" do
expected_query = Google::Firestore::V1::StructuredQuery.new(
where: Google::Firestore::V1::StructuredQuery::Filter.new(
field_filter: Google::Firestore::V1::StructuredQuery::FieldFilter.new(
field: Google::Firestore::V1::StructuredQuery::FieldReference.new(field_path: "foo"),
op: :IN,
value: Google::Firestore::V1::Value.new(
array_value: Google::Firestore::V1::ArrayValue.new(
values: [
Google::Firestore::V1::Value.new(integer_value: 42),
Google::Firestore::V1::Value.new(integer_value: 43)
]
)
)
)
)
)

generated_query = query.where(:foo, :in, [42, 43]).query
generated_query.must_equal expected_query
end

it "with multiple values" do
expected_query = Google::Firestore::V1::StructuredQuery.new(
where: Google::Firestore::V1::StructuredQuery::Filter.new(
composite_filter: Google::Firestore::V1::StructuredQuery::CompositeFilter.new(
op: :AND,
filters: [
Google::Firestore::V1::StructuredQuery::Filter.new(
field_filter: Google::Firestore::V1::StructuredQuery::FieldFilter.new(
field: Google::Firestore::V1::StructuredQuery::FieldReference.new(field_path: "foo"),
op: :IN,
value: Google::Firestore::V1::Value.new(
array_value: Google::Firestore::V1::ArrayValue.new(
values: [
Google::Firestore::V1::Value.new(integer_value: 42),
Google::Firestore::V1::Value.new(integer_value: 43)
]
)
)
)
),
Google::Firestore::V1::StructuredQuery::Filter.new(
field_filter: Google::Firestore::V1::StructuredQuery::FieldFilter.new(
field: Google::Firestore::V1::StructuredQuery::FieldReference.new(field_path: "foo"),
op: :IN,
value: Google::Firestore::V1::Value.new(
array_value: Google::Firestore::V1::ArrayValue.new(
values: [
Google::Firestore::V1::Value.new(integer_value: 43),
Google::Firestore::V1::Value.new(integer_value: 44)
]
)
)
)
)
]
)
)
)

generated_query = query.where(:foo, :in, [42, 43]).where(:foo, :in, [43, 44]).query
generated_query.must_equal expected_query
end
end

0 comments on commit 5a14fd6

Please sign in to comment.