Skip to content

Commit 8e36ed7

Browse files
authored
Firestore array queries (GoogleCloudPlatform#1959)
* Adding base code for firestore array support * Add array firestore snippets * fix double-quotes and single-quotes
1 parent bd98e43 commit 8e36ed7

File tree

2 files changed

+75
-21
lines changed

2 files changed

+75
-21
lines changed

firestore/cloud-client/snippets.py

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from time import sleep
1616

1717
from google.cloud import firestore
18+
from google.cloud.firestore_v1beta1 import ArrayRemove, ArrayUnion
1819
import google.cloud.exceptions
1920

2021

@@ -101,12 +102,14 @@ def add_data_types():
101102

102103
# [START custom_class_def]
103104
class City(object):
104-
def __init__(self, name, state, country, capital=False, population=0):
105+
def __init__(self, name, state, country, capital=False, population=0,
106+
regions=[]):
105107
self.name = name
106108
self.state = state
107109
self.country = country
108110
self.capital = capital
109111
self.population = population
112+
self.regions = regions
110113

111114
@staticmethod
112115
def from_dict(source):
@@ -119,6 +122,9 @@ def from_dict(source):
119122
if u'population' in source:
120123
city.population = source[u'population']
121124

125+
if u'regions' in source:
126+
city.regions = source[u'regions']
127+
122128
return city
123129
# [END_EXCLUDE]
124130

@@ -136,12 +142,17 @@ def to_dict(self):
136142
if self.population:
137143
dest[u'population'] = self.population
138144

145+
if self.regions:
146+
dest[u'regions'] = self.regions
147+
139148
return dest
140149
# [END_EXCLUDE]
141150

142151
def __repr__(self):
143-
return u'City(name={}, country={}, population={}, capital={})'.format(
144-
self.name, self.country, self.population, self.capital)
152+
return(
153+
u'City(name={}, country={}, population={}, capital={}, regions={})'
154+
.format(self.name, self.country, self.population, self.capital,
155+
self.regions))
145156
# [END custom_class_def]
146157

147158

@@ -150,15 +161,19 @@ def add_example_data():
150161
# [START add_example_data]
151162
cities_ref = db.collection(u'cities')
152163
cities_ref.document(u'SF').set(
153-
City(u'San Francisco', u'CA', u'USA', False, 860000).to_dict())
164+
City(u'San Francisco', u'CA', u'USA', False, 860000,
165+
[u'west_coast', u'norcal']).to_dict())
154166
cities_ref.document(u'LA').set(
155-
City(u'Los Angeles', u'CA', u'USA', False, 3900000).to_dict())
167+
City(u'Los Angeles', u'CA', u'USA', False, 3900000,
168+
[u'west_coast', u'socal']).to_dict())
156169
cities_ref.document(u'DC').set(
157-
City(u'Washington D.C.', None, u'USA', True, 680000).to_dict())
170+
City(u'Washington D.C.', None, u'USA', True, 680000,
171+
[u'east_coast']).to_dict())
158172
cities_ref.document(u'TOK').set(
159-
City(u'Tokyo', None, u'Japan', True, 9000000).to_dict())
173+
City(u'Tokyo', None, u'Japan', True, 9000000,
174+
[u'kanto', u'honshu']).to_dict())
160175
cities_ref.document(u'BJ').set(
161-
City(u'Beijing', None, u'China', True, 21500000).to_dict())
176+
City(u'Beijing', None, u'China', True, 21500000, [u'hebei']).to_dict())
162177
# [END add_example_data]
163178

164179

@@ -232,6 +247,18 @@ def get_simple_query():
232247
# [END get_simple_query]
233248

234249

250+
def array_contains_filter():
251+
db = firestore.Client()
252+
# [START fs_array_contains_filter]
253+
cities_ref = db.collection(u'cities')
254+
255+
query = cities_ref.where(u'regions', u'array_contains', u'west_coast')
256+
# [END fs_array_contains_filter]
257+
docs = query.get()
258+
for doc in docs:
259+
print(u'{} => {}'.format(doc.id, doc.to_dict()))
260+
261+
235262
def get_full_collection():
236263
db = firestore.Client()
237264
# [START get_full_collection]
@@ -286,6 +313,21 @@ def update_doc():
286313
# [END update_doc]
287314

288315

316+
def update_doc_array():
317+
db = firestore.Client()
318+
# [START fs_update_doc_array]
319+
city_ref = db.collection(u'cities').document(u'DC')
320+
321+
# Atomically add a new region to the 'regions' array field.
322+
city_ref.update({u'regions': ArrayUnion([u'greater_virginia'])})
323+
324+
# // Atomically remove a region from the 'regions' array field.
325+
city_ref.update({u'regions': ArrayRemove([u'east_coast'])})
326+
# [END fs_update_doc_array]
327+
city = city_ref.get()
328+
print(u'Updated the regions field of the DC. {}'.format(city.to_dict()))
329+
330+
289331
def update_multiple():
290332
db = firestore.Client()
291333
# [START update_multiple]
@@ -569,7 +611,7 @@ def snapshot_cursors():
569611
# [END fs_start_at_snapshot_query_cursor]
570612
results = start_at_snapshot.limit(10).get()
571613
for doc in results:
572-
print('{}'.format(doc.id))
614+
print(u'{}'.format(doc.id))
573615

574616
return results
575617

@@ -674,11 +716,11 @@ def on_snapshot(col_snapshot, changes, read_time):
674716
print(u'Callback received query snapshot.')
675717
print(u'Current cities in California: ')
676718
for change in changes:
677-
if change.type.name == "ADDED":
719+
if change.type.name == 'ADDED':
678720
print(u'New city: {}'.format(change.document.id))
679-
elif change.type.name == "MODIFIED":
721+
elif change.type.name == 'MODIFIED':
680722
print(u'Modified city: {}'.format(change.document.id))
681-
elif change.type.name == "REMOVED":
723+
elif change.type.name == 'REMOVED':
682724
print(u'Removed city: {}'.format(change.document.id))
683725

684726
col_query = db.collection(u'cities').where(u'state', u'==', u'CA')

firestore/cloud-client/snippets_test.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ def test_get_simple_query():
7474
snippets.get_simple_query()
7575

7676

77+
def test_array_contains_filter(capsys):
78+
snippets.array_contains_filter()
79+
out, _ = capsys.readouterr()
80+
assert 'SF' in out
81+
82+
7783
def test_get_full_collection():
7884
snippets.get_full_collection()
7985

@@ -110,6 +116,12 @@ def test_update_doc():
110116
snippets.update_doc()
111117

112118

119+
def test_update_doc_array(capsys):
120+
snippets.update_doc_array()
121+
out, _ = capsys.readouterr()
122+
assert 'greater_virginia' in out
123+
124+
113125
def test_update_multiple():
114126
snippets.update_multiple()
115127

@@ -198,9 +210,9 @@ def test_cursor_simple_end_at():
198210
def test_snapshot_cursors(capsys):
199211
snippets.snapshot_cursors()
200212
out, _ = capsys.readouterr()
201-
assert "SF" in out
202-
assert "TOK" in out
203-
assert "BJ" in out
213+
assert 'SF' in out
214+
assert 'TOK' in out
215+
assert 'BJ' in out
204216

205217

206218
def test_cursor_paginate():
@@ -223,22 +235,22 @@ def test_delete_field(db):
223235
def test_listen_document(capsys):
224236
snippets.listen_document()
225237
out, _ = capsys.readouterr()
226-
assert "Received document snapshot: SF" in out
238+
assert 'Received document snapshot: SF' in out
227239

228240

229241
def test_listen_multiple(capsys):
230242
snippets.listen_multiple()
231243
out, _ = capsys.readouterr()
232-
assert "Current cities in California:" in out
233-
assert "SF" in out
244+
assert 'Current cities in California:' in out
245+
assert 'SF' in out
234246

235247

236248
def test_listen_for_changes(capsys):
237249
snippets.listen_for_changes()
238250
out, _ = capsys.readouterr()
239-
assert "New city: MTV" in out
240-
assert "Modified city: MTV" in out
241-
assert "Removed city: MTV" in out
251+
assert 'New city: MTV' in out
252+
assert 'Modified city: MTV' in out
253+
assert 'Removed city: MTV' in out
242254

243255

244256
def test_delete_full_collection():

0 commit comments

Comments
 (0)