@@ -110,149 +110,6 @@ frameworks.
110
110
if __name__ == "__main__":
111
111
app.run()
112
112
113
- Query Works in the Shell But Not in {+driver-short+}
114
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
115
-
116
- After the ``_id`` field, which is always first, the key-value pairs in a BSON document can
117
- be in any order. The ``mongo`` shell preserves key order when reading and writing
118
- data, as shown by the fields "b" and "a" in the following code example:
119
-
120
- .. code-block:: javascript
121
-
122
- // mongo shell
123
- db.collection.insertOne( { "_id" : 1, "subdocument" : { "b" : 1, "a" : 1 } } )
124
- // Returns: WriteResult({ "nInserted" : 1 })
125
-
126
- db.collection.findOne()
127
- // Returns: { "_id" : 1, "subdocument" : { "b" : 1, "a" : 1 } }
128
-
129
- {+driver-short+} represents BSON documents as Python dictionaries by default,
130
- and the order of keys in dictionaries is not defined. In Python, a dictionary declared with
131
- the "a" key first is the same as one with the "b" key first. In the following example,
132
- the keys are displayed in the same order regardless of their order in the ``print``
133
- statement:
134
-
135
- .. code-block:: python
136
-
137
- print({'a': 1.0, 'b': 1.0})
138
- # Returns: {'a': 1.0, 'b': 1.0}
139
-
140
- print({'b': 1.0, 'a': 1.0})
141
- # Returns: {'a': 1.0, 'b': 1.0}
142
-
143
- Similarly, Python dictionaries might not show keys in the order they are
144
- stored in BSON. The following example shows the result of printing the document
145
- inserted in a preceding example:
146
-
147
- .. code-block:: python
148
-
149
- print(collection.find_one())
150
- # Returns: {'_id': 1.0, 'subdocument': {'a': 1.0, 'b': 1.0}}
151
-
152
- To preserve the order of keys when reading BSON, use the ``SON`` class,
153
- which is a dictionary that remembers its key order.
154
-
155
- The following code example shows how to create a collection
156
- configured to use the ``SON`` class:
157
-
158
- .. code-block:: python
159
-
160
- from bson import CodecOptions, SON
161
-
162
- opts = CodecOptions(document_class=SON)
163
-
164
- CodecOptions(document_class=...SON..., tz_aware=False, uuid_representation=UuidRepresentation.UNSPECIFIED, unicode_decode_error_handler='strict', tzinfo=None, type_registry=TypeRegistry(type_codecs=[], fallback_encoder=None), datetime_conversion=DatetimeConversion.DATETIME)
165
- collection_son = collection.with_options(codec_options=opts)
166
-
167
- When you find the preceding subdocument, the driver represents query results with
168
- ``SON`` objects and preserves key order:
169
-
170
- .. io-code-block::
171
-
172
- .. input::
173
- :language: python
174
-
175
- print(collection_son.find_one())
176
-
177
- .. output::
178
-
179
- SON([('_id', 1.0), ('subdocument', SON([('b', 1.0), ('a', 1.0)]))])
180
-
181
- The subdocument's actual storage layout is now visible: "b" is before "a".
182
-
183
- Because a Python dictionary's key order is not defined, you cannot predict how it will be
184
- serialized to BSON. However, MongoDB considers subdocuments equal only if their
185
- keys have the same order. If you use a Python dictionary to query on a subdocument, it may
186
- not match:
187
-
188
- .. io-code-block::
189
-
190
- .. input::
191
- :language: python
192
-
193
- collection.find_one({'subdocument': {'b': 1.0, 'a': 1.0}}) is None
194
-
195
- .. output::
196
-
197
- True
198
-
199
- Because Python considers the two dictionaries the same, swapping the key order in your query
200
- makes no difference:
201
-
202
- .. io-code-block::
203
-
204
- .. input::
205
- :language: python
206
-
207
- collection.find_one({'subdocument': {'b': 1.0, 'a': 1.0}}) is None
208
-
209
- .. output::
210
-
211
- True
212
-
213
- You can solve this in two ways. First, you can match the subdocument field-by-field:
214
-
215
- .. io-code-block::
216
-
217
- .. input::
218
- :language: python
219
-
220
- collection.find_one({'subdocument.a': 1.0,
221
- 'subdocument.b': 1.0})
222
-
223
- .. output::
224
-
225
- {'_id': 1.0, 'subdocument': {'a': 1.0, 'b': 1.0}}
226
-
227
- The query matches any subdocument with an "a" of 1.0 and a "b" of 1.0,
228
- regardless of the order in which you specify them in Python, or the order in which they're
229
- stored in BSON. This query also now matches subdocuments with additional
230
- keys besides "a" and "b", whereas the previous query required an exact match.
231
-
232
- The second solution is to use a ``~bson.son.SON`` object to specify the key order:
233
-
234
- .. io-code-block::
235
-
236
- .. input::
237
- :language: python
238
-
239
- query = {'subdocument': SON([('b', 1.0), ('a', 1.0)])}
240
- collection.find_one(query)
241
-
242
- .. output::
243
-
244
- {'_id': 1.0, 'subdocument': {'a': 1.0, 'b': 1.0}}
245
-
246
- The driver preserves the key order you use when you create a ``~bson.son.SON``
247
- when serializing it to BSON and using it as a query. Thus, you can create a
248
- subdocument that exactly matches the subdocument in the collection.
249
-
250
- .. note::
251
-
252
- For more information about subdocument matching, see the
253
- `Query on Embedded/Nested Documents <https://www.mongodb.com/docs/manual/tutorial/query-embedded-documents/>`__
254
- guide in the {+mdb-server+} documentation.
255
-
256
113
Cursors
257
114
-------
258
115
0 commit comments