/
cursor.xml
312 lines (272 loc) · 12.8 KB
/
cursor.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 57a945c977e3e6d274895f44645c703ebcacfa3c Maintainer: lex Status: ready -->
<!-- Reviewed: no -->
<phpdoc:classref xml:id="class.mongodb-driver-cursor" xmlns:phpdoc="http://php.net/ns/phpdoc" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude">
<title>Класс MongoDB\Driver\Cursor</title>
<titleabbrev>MongoDB\Driver\Cursor</titleabbrev>
<partintro>
<!-- {{{ MongoDB\Driver\Cursor intro -->
<section xml:id="mongodb-driver-cursor.intro">
&reftitle.intro;
<para>
Класс <classname>MongoDB\Driver\Cursor</classname> содержит
результаты команды MongoDB command или запроса и может быть возвращён
<methodname>MongoDB\Driver\Manager::executeCommand</methodname> или
<methodname>MongoDB\Driver\Manager::executeQuery</methodname> соответственно.
</para>
</section>
<!-- }}} -->
<section xml:id="mongodb-driver-cursor.synopsis">
&reftitle.classsynopsis;
<!-- {{{ Synopsis -->
<classsynopsis>
<ooclass><classname>MongoDB\Driver\Cursor</classname></ooclass>
<!-- {{{ Class synopsis -->
<classsynopsisinfo>
<modifier>final</modifier>
<ooclass>
<classname>MongoDB\Driver\Cursor</classname>
</ooclass>
<oointerface>
<interfacename>MongoDB\Driver\CursorInterface</interfacename>
</oointerface>
<oointerface>
<interfacename>Iterator</interfacename>
</oointerface>
</classsynopsisinfo>
<!-- }}} -->
<classsynopsisinfo role="comment">&Methods;</classsynopsisinfo>
<xi:include xpointer="xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class.mongodb-driver-cursor')/db:refentry/db:refsect1[@role='description']/descendant::db:methodsynopsis[not(@role='procedural')])" />
</classsynopsis>
<!-- }}} -->
</section>
<section role="changelog">
&reftitle.changelog;
<para>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>&Version;</entry>
<entry>&Description;</entry>
</row>
</thead>
<tbody>
<row>
<entry>PECL mongodb 1.9.0</entry>
<entry>
Реализует <interfacename>Iterator</interfacename>.
</entry>
</row>
<row>
<entry>PECL mongodb 1.6.0</entry>
<entry>
Реализует <interfacename>MongoDB\Driver\CursorInterface</interfacename>, который наследует <interfacename>Traversable</interfacename>.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</section>
<section xml:id="mongodb-driver-cursor.examples">
&reftitle.examples;
<example xml:id="mongodb-driver-cursor.examples.foreach">
<title>Reading a result set</title>
<para>
Как <methodname>MongoDB\Driver\Manager::executeCommand</methodname>, так
<methodname>MongoDB\Driver\Manager::executeQuery</methodname>, возвращают
свои результаты в виде объекта <classname>MongoDB\Driver\Cursor</classname>.
</para>
<para>
Поскольку <classname>MongoDB\Driver\Cursor</classname> реализует интерфейс
<interfacename>Traversable</interfacename>, вы можете
итерировать по набору результата с помощью
<link linkend="control-structures.foreach"><literal>foreach</literal></link>.
</para>
<programlisting role="php">
<![CDATA[
<?php
$manager = new MongoDB\Driver\Manager();
/* Вставить определённые документы, чтобы наш запрос вернул результаты */
$bulkWrite = new MongoDB\Driver\BulkWrite;
$bulkWrite->insert(['name' => 'Ceres', 'size' => 946, 'distance' => 2.766]);
$bulkWrite->insert(['name' => 'Vesta', 'size' => 525, 'distance' => 2.362]);
$manager->executeBulkWrite("test.asteroids", $bulkWrite);
/* Запрос на получение всех элементов в коллекции */
$query = new MongoDB\Driver\Query( [] );
/* Запрос коллекции "asteroids" базы данных "test" */
$cursor = $manager->executeQuery("test.asteroids", $query);
/* Теперь $cursor содержит объект, обёрнутый вокруг набора с результатом. Используйте
* foreach() для итеации по всему результату */
foreach ($cursor as $document) {
print_r($document);
}
?>
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
stdClass Object
(
[_id] => MongoDB\BSON\ObjectId Object
(
[oid] => 5a4cff2f122d3321565d8cc2
)
[name] => Ceres
[size] => 946
[distance] => 2.766
)
stdClass Object
(
[_id] => MongoDB\BSON\ObjectId Object
(
[oid] => 5a4cff2f122d3321565d8cc3
)
[name] => Vesta
[size] => 525
[distance] => 2.362
}
]]>
</screen>
</example>
<example xml:id="mongodb-driver-cursor.examples.tailable">
<title>Чтение набора результатов для хвостового курсора</title>
<para>
<link xlink:href="&url.mongodb.docs;core/tailable-cursors">Хвостовые курсоры</link> -
- это особый тип курсора MongoDB, который позволяет клиенту читать некоторые результаты,
а затем ждать, пока не появятся дополнительные документы.
Эти курсоры в основном используются с
<link xlink:href="&url.mongodb.docs;core/capped-collections">Capped Collections</link>
и <link xlink:href="&url.mongodb.docs;changeStreams">Change Streams</link>.
</para>
<para>
Хотя обычные курсоры можно итерировать один раз с помощью <literal>foreach</literal>,
этот подход не будет работать с хвостовыми курсорами.
Когда <literal>foreach</literal> используется с хвостовым курсором,
цикл останавливается по достижении конца начального набора результатов.
Попытка продолжить итерацию курсора со вторым <literal>foreach</literal> выбросить исключение,
поскольку PHP пытается перемотать курсор. Подобно объектам результатов в других драйверах баз данных,
курсоры в MongoDB поддерживают только итерацию вперёд, что означает, что они не могут быть перемотаны.
</para>
<para>
Для непрерывного считывания с хвостового курсора объект курсора должен быть завернут
с помощью <classname>IteratorIterator</classname>. Это позволяет приложению напрямую управлять
итерацией курсора, избегать непреднамеренного перемотки курсора и решать, когда ждать новых результатов
или полностью прекратить итерацию.
</para>
<para>
Чтобы продемонстрировать хвостовой курсор в действии,
будут использоваться два скрипта: "производитель" (producer) и "потребитель" (consumer).
Скрипт продюсера создаст новую capped-коллекцию, используя команду
<link xlink:href="&url.mongodb.docs.command;create">create</link>
и начнёт вставку нового документа в эту коллекцию каждую секунду.
</para>
<programlisting role="php">
<![CDATA[
<?php
$manager = new MongoDB\Driver\Manager;
$manager->executeCommand('test', new MongoDB\Driver\Command([
'create' => 'asteroids',
'capped' => true,
'size' => 1048576,
]));
while (true) {
$bulkWrite = new MongoDB\Driver\BulkWrite;
$bulkWrite->insert(['createdAt' => new MongoDB\BSON\UTCDateTime]);
$manager->executeBulkWrite('test.asteroids', $bulkWrite);
sleep(1);
}
?>
]]>
</programlisting>
<para>
Когда скрипт продюсера (producer) всё ещё запущен,
может быть выполнен второй пользовательский скрипт для чтения вставленных документов
с помощью хвостового (tailable) курсора, обозначенного параметрами
<literal>tailable</literal> и <literal>awaitData</literal>
для <function>MongoDB\Driver\Query::__construct</function>.
</para>
<programlisting role="php">
<![CDATA[
<?php
$manager = new MongoDB\Driver\Manager;
$query = new MongoDB\Driver\Query([], [
'tailable' => true,
'awaitData' => true,
]);
$cursor = $manager->executeQuery('test.asteroids', $query);
$iterator = new IteratorIterator($cursor);
$iterator->rewind();
while (true) {
if ($iterator->valid()) {
$document = $iterator->current();
printf("Пользовательский документ создан: %s\n", $document->createdAt);
}
$iterator->next();
}
?>
]]>
</programlisting>
<para>
Пользовательский скрипт начнёт с быстрой печати всех доступных документов
в заблокированной коллекции (как если бы использовался <literal>foreach</literal>);
однако при достижении конца начального набора результатов он не завершится.
Так как курсор является хвостовым, вызов <function>IteratorIterator::valid</function>
будет блокировать и ждать дополнительных результатов.
<function>IteratorIterator::valid</function> также используется для проверки наличия на
каждом этапе данных, доступных для чтения.
</para>
<note>
<simpara>
В этом примере используется опция запроса <literal>awaitData</literal>,
чтобы проинструктировать сервер блокировать в течение короткого периода
(например, одну секунду) в конце набора результатов перед возвратом ответа драйверу.
Это используется для предотвращения агрессивного опроса (polling) сервера
при отсутствии результатов. Параметр <literal>maxAwaitTimeMS</literal> может
использоваться в сочетании с <literal>tailable</literal> и <literal>awaitData</literal>,
чтобы указать время, которое сервер должен блокировать, когда он достигнет конца набора результатов.
</simpara>
</note>
</example>
</section>
<section role="errors">
&reftitle.errors;
<simpara>
При итерации по объекту курсора данные BSON преобразуются в переменные PHP.
Эта итерация может вызвать следующие исключения:
</simpara>
<simplelist>
<member>
Выбрасывает
<classname>MongoDB\Driver\Exception\InvalidArgumentException</classname>,
если класс на карте типов не может быть создан или не реализует
<interfacename>MongoDB\BSON\Unserializable</interfacename>.
</member>
&mongodb.throws.bson.unexpected;
</simplelist>
</section>
</partintro>
&reference.mongodb.mongodb.driver.entities.cursor;
</phpdoc:classref>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->