Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
mongo-php-library
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
sinan
mongo-php-library
Commits
c2922d30
Unverified
Commit
c2922d30
authored
Jul 23, 2019
by
Andreas Braun
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
PHPLIB-402: Add aggregation helper to Database class
parent
a9513dce
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
1743 additions
and
66 deletions
+1743
-66
apiargs-MongoDBCollection-method-aggregate-option.yaml
...es/apiargs-MongoDBCollection-method-aggregate-option.yaml
+25
-57
apiargs-MongoDBDatabase-method-aggregate-option.yaml
...udes/apiargs-MongoDBDatabase-method-aggregate-option.yaml
+55
-0
apiargs-MongoDBDatabase-method-aggregate-param.yaml
...ludes/apiargs-MongoDBDatabase-method-aggregate-param.yaml
+14
-0
apiargs-aggregate-option.yaml
docs/includes/apiargs-aggregate-option.yaml
+62
-0
MongoDBDatabase.txt
docs/reference/class/MongoDBDatabase.txt
+1
-0
MongoDBCollection-aggregate.txt
docs/reference/method/MongoDBCollection-aggregate.txt
+2
-1
MongoDBDatabase-aggregate.txt
docs/reference/method/MongoDBDatabase-aggregate.txt
+63
-0
crud.txt
docs/tutorial/crud.txt
+1
-1
Database.php
src/Database.php
+59
-0
CommandExpectations.php
tests/SpecTests/CommandExpectations.php
+10
-0
Context.php
tests/SpecTests/Context.php
+11
-0
CrudSpecTest.php
tests/SpecTests/CrudSpecTest.php
+123
-0
Operation.php
tests/SpecTests/Operation.php
+24
-7
ResultExpectation.php
tests/SpecTests/ResultExpectation.php
+13
-0
aggregate-merge.json
tests/SpecTests/crud/aggregate-merge.json
+415
-0
aggregate-out-readConcern.json
tests/SpecTests/crud/aggregate-out-readConcern.json
+385
-0
bulkWrite-arrayFilters.json
tests/SpecTests/crud/bulkWrite-arrayFilters.json
+160
-0
db-aggregate.json
tests/SpecTests/crud/db-aggregate.json
+81
-0
updateWithPipelines.json
tests/SpecTests/crud/updateWithPipelines.json
+239
-0
No files found.
docs/includes/apiargs-MongoDBCollection-method-aggregate-option.yaml
View file @
c2922d30
arg_name
:
option
source
:
name
:
allowDiskUse
file
:
apiargs-aggregate-option.yaml
type
:
boolean
ref
:
allowDiskUse
description
:
|
Enables writing to temporary files. When set to ``true``, aggregation stages
can write data to the ``_tmp`` sub-directory in the ``dbPath`` directory. The
default is ``false``.
interface
:
phpmethod
operation
:
~
optional
:
true
---
---
arg_name
:
option
source
:
name
:
batchSize
file
:
apiargs-aggregate-option.yaml
type
:
integer
ref
:
batchSize
description
:
|
Specifies the initial batch size for the cursor. A batchSize of ``0`` means an
empty first batch and is useful for quickly returning a cursor or failure
message without doing significant server-side work.
interface
:
phpmethod
operation
:
~
optional
:
true
---
---
source
:
source
:
file
:
apiargs-
MongoDBCollection-common
-option.yaml
file
:
apiargs-
aggregate
-option.yaml
ref
:
bypassDocumentValidation
ref
:
bypassDocumentValidation
post
:
|
This only applies when using the :ref:`$out <agg-out>` stage.
Document validation requires MongoDB 3.2 or later: if you are using an earlier
version of MongoDB, this option will be ignored.
---
---
arg_name
:
option
source
:
name
:
comment
file
:
apiargs-aggregate-option.yaml
type
:
string
ref
:
comment
description
:
|
post
:
|
Users can specify an arbitrary string to help trace the operation through the
database profiler, currentOp, and logs.
.. versionadded:: 1.3
.. versionadded:: 1.3
interface
:
phpmethod
operation
:
~
optional
:
true
---
---
arg_name
:
option
source
:
name
:
explain
file
:
apiargs-aggregate-option.yaml
type
:
boolean
ref
:
explain
description
:
|
post
:
|
Specifies whether or not to return the information on the processing of the
pipeline.
.. versionadded:: 1.4
.. versionadded:: 1.4
interface
:
phpmethod
operation
:
~
optional
:
true
---
---
arg_name
:
option
source
:
name
:
hint
file
:
apiargs-aggregate-option.yaml
type
:
string|array|object
ref
:
hint
description
:
|
post
:
|
The index to use. Specify either the index name as a string or the index key
pattern as a document. If specified, then the query system will only consider
plans using the hinted index.
.. versionadded:: 1.3
.. versionadded:: 1.3
interface
:
phpmethod
operation
:
~
optional
:
true
---
---
source
:
source
:
file
:
apiargs-common-option.yaml
file
:
apiargs-common-option.yaml
...
@@ -96,6 +58,12 @@ type: boolean
...
@@ -96,6 +58,12 @@ type: boolean
description
:
|
description
:
|
Indicates whether the command will request that the server provide results
Indicates whether the command will request that the server provide results
using a cursor. The default is ``true``.
using a cursor. The default is ``true``.
.. note::
MongoDB 3.6+ no longer supports returning results without a cursor (excluding
when the explain option is used) and specifying false for this option will
result in a server error.
interface
:
phpmethod
interface
:
phpmethod
operation
:
~
operation
:
~
optional
:
true
optional
:
true
...
...
docs/includes/apiargs-MongoDBDatabase-method-aggregate-option.yaml
0 → 100644
View file @
c2922d30
source
:
file
:
apiargs-aggregate-option.yaml
ref
:
allowDiskUse
---
source
:
file
:
apiargs-aggregate-option.yaml
ref
:
batchSize
---
source
:
file
:
apiargs-aggregate-option.yaml
ref
:
bypassDocumentValidation
---
source
:
file
:
apiargs-aggregate-option.yaml
ref
:
comment
---
source
:
file
:
apiargs-aggregate-option.yaml
ref
:
explain
---
source
:
file
:
apiargs-aggregate-option.yaml
ref
:
hint
---
source
:
file
:
apiargs-common-option.yaml
ref
:
maxTimeMS
---
source
:
file
:
apiargs-MongoDBDatabase-common-option.yaml
ref
:
readConcern
---
source
:
file
:
apiargs-MongoDBDatabase-common-option.yaml
ref
:
readPreference
post
:
|
This option will be ignored when using the :ref:`$out <agg-out>` stage.
---
source
:
file
:
apiargs-common-option.yaml
ref
:
session
---
source
:
file
:
apiargs-MongoDBDatabase-common-option.yaml
ref
:
typeMap
---
source
:
file
:
apiargs-MongoDBDatabase-common-option.yaml
ref
:
writeConcern
post
:
|
This only applies when the :ref:`$out <agg-out>` stage is specified.
This is not supported for server versions prior to 3.4 and will result in an
exception at execution time if used.
...
docs/includes/apiargs-MongoDBDatabase-method-aggregate-param.yaml
0 → 100644
View file @
c2922d30
arg_name
:
param
name
:
$pipeline
type
:
array
description
:
|
Specifies an :manual:`aggregation pipeline </core/aggregation-pipeline>`
operation.
interface
:
phpmethod
operation
:
~
optional
:
false
---
source
:
file
:
apiargs-common-param.yaml
ref
:
$options
...
docs/includes/apiargs-aggregate-option.yaml
0 → 100644
View file @
c2922d30
arg_name
:
option
name
:
allowDiskUse
type
:
boolean
description
:
|
Enables writing to temporary files. When set to ``true``, aggregation stages
can write data to the ``_tmp`` sub-directory in the ``dbPath`` directory. The
default is ``false``.
interface
:
phpmethod
operation
:
~
optional
:
true
---
arg_name
:
option
name
:
batchSize
type
:
integer
description
:
|
Specifies the initial batch size for the cursor. A batchSize of ``0`` means an
empty first batch and is useful for quickly returning a cursor or failure
message without doing significant server-side work.
interface
:
phpmethod
operation
:
~
optional
:
true
---
source
:
file
:
apiargs-MongoDBCollection-common-option.yaml
ref
:
bypassDocumentValidation
post
:
|
This only applies when using the :ref:`$out <agg-out>` stage.
Document validation requires MongoDB 3.2 or later: if you are using an earlier
version of MongoDB, this option will be ignored.
---
arg_name
:
option
name
:
comment
type
:
string
description
:
|
Users can specify an arbitrary string to help trace the operation through the
database profiler, currentOp, and logs.
interface
:
phpmethod
operation
:
~
optional
:
true
---
arg_name
:
option
name
:
explain
type
:
boolean
description
:
|
Specifies whether or not to return the information on the processing of the
pipeline.
interface
:
phpmethod
operation
:
~
optional
:
true
---
arg_name
:
option
name
:
hint
type
:
string|array|object
description
:
|
The index to use. Specify either the index name as a string or the index key
pattern as a document. If specified, then the query system will only consider
plans using the hinted index.
interface
:
phpmethod
operation
:
~
optional
:
true
...
docs/reference/class/MongoDBDatabase.txt
View file @
c2922d30
...
@@ -45,6 +45,7 @@ Methods
...
@@ -45,6 +45,7 @@ Methods
/reference/method/MongoDBDatabase__construct
/reference/method/MongoDBDatabase__construct
/reference/method/MongoDBDatabase__get
/reference/method/MongoDBDatabase__get
/reference/method/MongoDBDatabase-aggregate
/reference/method/MongoDBDatabase-command
/reference/method/MongoDBDatabase-command
/reference/method/MongoDBDatabase-createCollection
/reference/method/MongoDBDatabase-createCollection
/reference/method/MongoDBDatabase-drop
/reference/method/MongoDBDatabase-drop
...
...
docs/reference/method/MongoDBCollection-aggregate.txt
View file @
c2922d30
...
@@ -45,7 +45,7 @@ Errors/Exceptions
...
@@ -45,7 +45,7 @@ Errors/Exceptions
.. include:: /includes/extracts/error-invalidargumentexception.rst
.. include:: /includes/extracts/error-invalidargumentexception.rst
.. include:: /includes/extracts/error-driver-runtimeexception.rst
.. include:: /includes/extracts/error-driver-runtimeexception.rst
.. _php-agg-method-behavior:
.. _php-
coll-
agg-method-behavior:
Behavior
Behavior
--------
--------
...
@@ -63,6 +63,7 @@ value will be :php:`Traversable <traversable>`.
...
@@ -63,6 +63,7 @@ value will be :php:`Traversable <traversable>`.
See Also
See Also
--------
--------
- :phpmethod:`MongoDB\\Database::aggregate()`
- :manual:`aggregate </reference/command/aggregate>` command reference in the
- :manual:`aggregate </reference/command/aggregate>` command reference in the
MongoDB manual
MongoDB manual
- :manual:`Aggregation Pipeline </core/aggregation-pipeline>` documentation in
- :manual:`Aggregation Pipeline </core/aggregation-pipeline>` documentation in
...
...
docs/reference/method/MongoDBDatabase-aggregate.txt
0 → 100644
View file @
c2922d30
==============================
MongoDB\\Database::aggregate()
==============================
.. versionadded:: 1.5
.. default-domain:: mongodb
.. contents:: On this page
:local:
:backlinks: none
:depth: 1
:class: singlecol
Definition
----------
.. phpmethod:: MongoDB\\Database::aggregate()
Runs a specified :manual:`admin/diagnostic pipeline
</reference/operator/aggregation-pipeline/#db-aggregate-stages>` which does
not require an underlying collection. For aggregations on collection data,
see :phpmethod:`MongoDB\\Collection::aggregate()`.
.. code-block:: php
function aggregate(array $pipeline, array $options = []): Traversable
This method has the following parameters:
.. include:: /includes/apiargs/MongoDBDatabase-method-aggregate-param.rst
The ``$options`` parameter supports the following options:
.. include:: /includes/apiargs/MongoDBDatabase-method-aggregate-option.rst
Return Values
-------------
A :php:`MongoDB\\Driver\\Cursor <class.mongodb-driver-cursor>` or
:php:`ArrayIterator <arrayiterator>` object. In both cases, the return value
will be :php:`Traversable <traversable>`.
Errors/Exceptions
-----------------
.. include:: /includes/extracts/error-unexpectedvalueexception.rst
.. include:: /includes/extracts/error-unsupportedexception.rst
.. include:: /includes/extracts/error-invalidargumentexception.rst
.. include:: /includes/extracts/error-driver-runtimeexception.rst
.. _php-db-agg-method-behavior:
.. todo: add examples
See Also
--------
- :phpmethod:`MongoDB\\Collection::aggregate()`
- :manual:`aggregate </reference/command/aggregate>` command reference in the
MongoDB manual
- :manual:`Aggregation Pipeline </core/aggregation-pipeline>` documentation in
the MongoDB Manual
docs/tutorial/crud.txt
View file @
c2922d30
...
@@ -401,7 +401,7 @@ The |php-library|\'s :phpmethod:`MongoDB\\Collection::aggregate()` method
...
@@ -401,7 +401,7 @@ The |php-library|\'s :phpmethod:`MongoDB\\Collection::aggregate()` method
returns a :php:`Traversable <traversable>` object, which you can iterate upon to
returns a :php:`Traversable <traversable>` object, which you can iterate upon to
access the results of the aggregation operation. Refer to the
access the results of the aggregation operation. Refer to the
:phpmethod:`MongoDB\\Collection::aggregate()` method's :ref:`behavior
:phpmethod:`MongoDB\\Collection::aggregate()` method's :ref:`behavior
reference <php-agg-method-behavior>` for more about the method's output.
reference <php-
coll-
agg-method-behavior>` for more about the method's output.
The following example lists the 5 US states with the most zip codes associated
The following example lists the 5 US states with the most zip codes associated
with them:
with them:
...
...
src/Database.php
View file @
c2922d30
...
@@ -25,9 +25,11 @@ use MongoDB\Driver\ReadPreference;
...
@@ -25,9 +25,11 @@ use MongoDB\Driver\ReadPreference;
use
MongoDB\Driver\WriteConcern
;
use
MongoDB\Driver\WriteConcern
;
use
MongoDB\Driver\Exception\RuntimeException
as
DriverRuntimeException
;
use
MongoDB\Driver\Exception\RuntimeException
as
DriverRuntimeException
;
use
MongoDB\Exception\InvalidArgumentException
;
use
MongoDB\Exception\InvalidArgumentException
;
use
MongoDB\Exception\UnexpectedValueException
;
use
MongoDB\Exception\UnsupportedException
;
use
MongoDB\Exception\UnsupportedException
;
use
MongoDB\GridFS\Bucket
;
use
MongoDB\GridFS\Bucket
;
use
MongoDB\Model\CollectionInfoIterator
;
use
MongoDB\Model\CollectionInfoIterator
;
use
MongoDB\Operation\Aggregate
;
use
MongoDB\Operation\CreateCollection
;
use
MongoDB\Operation\CreateCollection
;
use
MongoDB\Operation\DatabaseCommand
;
use
MongoDB\Operation\DatabaseCommand
;
use
MongoDB\Operation\DropCollection
;
use
MongoDB\Operation\DropCollection
;
...
@@ -35,6 +37,7 @@ use MongoDB\Operation\DropDatabase;
...
@@ -35,6 +37,7 @@ use MongoDB\Operation\DropDatabase;
use
MongoDB\Operation\ListCollections
;
use
MongoDB\Operation\ListCollections
;
use
MongoDB\Operation\ModifyCollection
;
use
MongoDB\Operation\ModifyCollection
;
use
MongoDB\Operation\Watch
;
use
MongoDB\Operation\Watch
;
use
Traversable
;
class
Database
class
Database
{
{
...
@@ -155,6 +158,62 @@ class Database
...
@@ -155,6 +158,62 @@ class Database
return
$this
->
databaseName
;
return
$this
->
databaseName
;
}
}
/**
* Runs an aggregation framework pipeline on the database for pipeline
* stages that do not require an underlying collection, such as $currentOp
* and $listLocalSessions. Requires MongoDB >= 3.6
*
* @see Aggregate::__construct() for supported options
* @param array $pipeline List of pipeline operations
* @param array $options Command options
* @return Traversable
* @throws UnexpectedValueException if the command response was malformed
* @throws UnsupportedException if options are not supported by the selected server
* @throws InvalidArgumentException for parameter/option parsing errors
* @throws DriverRuntimeException for other driver errors (e.g. connection errors)
*/
public
function
aggregate
(
array
$pipeline
,
array
$options
=
[])
{
$hasOutStage
=
\MongoDB\is_last_pipeline_operator_out
(
$pipeline
);
if
(
!
isset
(
$options
[
'readPreference'
]))
{
$options
[
'readPreference'
]
=
$this
->
readPreference
;
}
if
(
$hasOutStage
)
{
$options
[
'readPreference'
]
=
new
ReadPreference
(
ReadPreference
::
RP_PRIMARY
);
}
$server
=
$this
->
manager
->
selectServer
(
$options
[
'readPreference'
]);
/* A "majority" read concern is not compatible with the $out stage, so
* avoid providing the Collection's read concern if it would conflict.
*
* A read concern is also not compatible with transactions.
*/
if
(
!
isset
(
$options
[
'readConcern'
])
&&
!
(
$hasOutStage
&&
$this
->
readConcern
->
getLevel
()
===
ReadConcern
::
MAJORITY
)
&&
\MongoDB\server_supports_feature
(
$server
,
self
::
$wireVersionForReadConcern
)
&&
!
\MongoDB\is_in_transaction
(
$options
))
{
$options
[
'readConcern'
]
=
$this
->
readConcern
;
}
if
(
!
isset
(
$options
[
'typeMap'
]))
{
$options
[
'typeMap'
]
=
$this
->
typeMap
;
}
if
(
$hasOutStage
&&
!
isset
(
$options
[
'writeConcern'
])
&&
\MongoDB\server_supports_feature
(
$server
,
self
::
$wireVersionForWritableCommandWriteConcern
)
&&
!
\MongoDB\is_in_transaction
(
$options
))
{
$options
[
'writeConcern'
]
=
$this
->
writeConcern
;
}
$operation
=
new
Aggregate
(
$this
->
databaseName
,
null
,
$pipeline
,
$options
);
return
$operation
->
execute
(
$server
);
}
/**
/**
* Execute a command on this database.
* Execute a command on this database.
*
*
...
...
tests/SpecTests/CommandExpectations.php
View file @
c2922d30
...
@@ -64,6 +64,16 @@ class CommandExpectations implements CommandSubscriber
...
@@ -64,6 +64,16 @@ class CommandExpectations implements CommandSubscriber
return
new
self
(
$expectedEvents
);
return
new
self
(
$expectedEvents
);
}
}
public
static
function
fromCrud
(
array
$expectedEvents
)
{
$o
=
new
self
(
$expectedEvents
);
$o
->
ignoreCommandFailed
=
true
;
$o
->
ignoreCommandSucceeded
=
true
;
return
$o
;
}
public
static
function
fromTransactions
(
array
$expectedEvents
)
public
static
function
fromTransactions
(
array
$expectedEvents
)
{
{
$o
=
new
self
(
$expectedEvents
);
$o
=
new
self
(
$expectedEvents
);
...
...
tests/SpecTests/Context.php
View file @
c2922d30
...
@@ -53,6 +53,17 @@ final class Context
...
@@ -53,6 +53,17 @@ final class Context
return
$o
;
return
$o
;
}
}
public
static
function
fromCrud
(
stdClass
$test
,
$databaseName
,
$collectionName
)
{
$o
=
new
self
(
$databaseName
,
$collectionName
);
$clientOptions
=
isset
(
$test
->
clientOptions
)
?
(
array
)
$test
->
clientOptions
:
[];
$o
->
client
=
new
Client
(
FunctionalTestCase
::
getUri
(),
$clientOptions
);
return
$o
;
}
public
static
function
fromRetryableWrites
(
stdClass
$test
,
$databaseName
,
$collectionName
)
public
static
function
fromRetryableWrites
(
stdClass
$test
,
$databaseName
,
$collectionName
)
{
{
$o
=
new
self
(
$databaseName
,
$collectionName
);
$o
=
new
self
(
$databaseName
,
$collectionName
);
...
...
tests/SpecTests/CrudSpecTest.php
0 → 100644
View file @
c2922d30
<?php
namespace
MongoDB\Tests\SpecTests
;
use
stdClass
;
/**
* Crud spec tests.
*
* @see https://github.com/mongodb/specifications/tree/master/source/crud
*/
class
CrudSpecTest
extends
FunctionalTestCase
{
/* These should all pass before the driver can be considered compatible with
* MongoDB 4.2. */
private
static
$incompleteTests
=
[
'aggregate-merge: Aggregate with $merge'
=>
'PHPLIB-438'
,
'aggregate-merge: Aggregate with $merge and batch size of 0'
=>
'PHPLIB-438'
,
'aggregate-merge: Aggregate with $merge and majority readConcern'
=>
'PHPLIB-438'
,
'aggregate-merge: Aggregate with $merge and local readConcern'
=>
'PHPLIB-438'
,
'aggregate-merge: Aggregate with $merge and available readConcern'
=>
'PHPLIB-438'
,
'aggregate-out-readConcern: readConcern majority with out stage'
=>
'PHPLIB-431'
,
'aggregate-out-readConcern: readConcern local with out stage'
=>
'PHPLIB-431'
,
'aggregate-out-readConcern: readConcern available with out stage'
=>
'PHPLIB-431'
,
'aggregate-out-readConcern: readConcern linearizable with out stage'
=>
'PHPLIB-431'
,
'aggregate-out-readConcern: invalid readConcern with out stage'
=>
'PHPLIB-431'
,
'bulkWrite-arrayFilters: BulkWrite with arrayFilters'
=>
'Fails due to command assertions'
,
'updateWithPipelines: UpdateOne using pipelines'
=>
'PHPLIB-418'
,
'updateWithPipelines: UpdateMany using pipelines'
=>
'PHPLIB-418'
,
'updateWithPipelines: FindOneAndUpdate using pipelines'
=>
'PHPLIB-418'
,
];
/**
* Assert that the expected and actual command documents match.
*
* Note: this method may modify the $expected object.
*
* @param stdClass $expected Expected command document
* @param stdClass $actual Actual command document
*/
public
static
function
assertCommandMatches
(
stdClass
$expected
,
stdClass
$actual
)
{
static
::
assertDocumentsMatch
(
$expected
,
$actual
);
}
/**
* Execute an individual test case from the specification.
*
* @dataProvider provideTests
* @param string $name Test name
* @param stdClass $test Individual "tests[]" document
* @param array $runOn Top-level "runOn" array with server requirements
* @param array $data Top-level "data" array to initialize collection
* @param string $databaseName Name of database under test
* @param string $collectionName Name of collection under test
*/
public
function
testCrud
(
$name
,
stdClass
$test
,
array
$runOn
=
null
,
array
$data
,
$databaseName
=
null
,
$collectionName
=
null
)
{
if
(
isset
(
self
::
$incompleteTests
[
$name
]))
{
$this
->
markTestIncomplete
(
self
::
$incompleteTests
[
$name
]);
}
if
(
isset
(
$runOn
))
{
$this
->
checkServerRequirements
(
$runOn
);
}
if
(
isset
(
$test
->
skipReason
))
{
$this
->
markTestSkipped
(
$test
->
skipReason
);
}
$databaseName
=
isset
(
$databaseName
)
?
$databaseName
:
$this
->
getDatabaseName
();
$collectionName
=
isset
(
$collectionName
)
?
$collectionName
:
$this
->
getCollectionName
();
$context
=
Context
::
fromCrud
(
$test
,
$databaseName
,
$collectionName
);
$this
->
setContext
(
$context
);
$this
->
dropTestAndOutcomeCollections
();
$this
->
insertDataFixtures
(
$data
);
if
(
isset
(
$test
->
failPoint
))
{
$this
->
configureFailPoint
(
$test
->
failPoint
);
}
if
(
isset
(
$test
->
expectations
))
{
$commandExpectations
=
CommandExpectations
::
fromCrud
(
$test
->
expectations
);
$commandExpectations
->
startMonitoring
();
}
foreach
(
$test
->
operations
as
$operation
)
{
Operation
::
fromCrud
(
$operation
)
->
assert
(
$this
,
$context
);
}
if
(
isset
(
$commandExpectations
))
{
$commandExpectations
->
stopMonitoring
();
$commandExpectations
->
assert
(
$this
,
$context
);
}
if
(
isset
(
$test
->
outcome
->
collection
->
data
))
{
$this
->
assertOutcomeCollectionData
(
$test
->
outcome
->
collection
->
data
);
}
}
public
function
provideTests
()
{
$testArgs
=
[];
foreach
(
glob
(
__DIR__
.
'/crud/*.json'
)
as
$filename
)
{
$json
=
$this
->
decodeJson
(
file_get_contents
(
$filename
));
$group
=
basename
(
$filename
,
'.json'
);
$runOn
=
isset
(
$json
->
runOn
)
?
$json
->
runOn
:
null
;
$data
=
isset
(
$json
->
data
)
?
$json
->
data
:
[];
$databaseName
=
isset
(
$json
->
database_name
)
?
$json
->
database_name
:
null
;
$collectionName
=
isset
(
$json
->
collection_name
)
?
$json
->
collection_name
:
null
;
foreach
(
$json
->
tests
as
$test
)
{
$name
=
$group
.
': '
.
$test
->
description
;
$testArgs
[
$name
]
=
[
$name
,
$test
,
$runOn
,
$data
,
$databaseName
,
$collectionName
];
}
}
return
$testArgs
;
}
}
tests/SpecTests/Operation.php
View file @
c2922d30
...
@@ -33,7 +33,6 @@ final class Operation
...
@@ -33,7 +33,6 @@ final class Operation
private
$collectionName
;
private
$collectionName
;
private
$collectionOptions
=
[];
private
$collectionOptions
=
[];
private
$databaseName
;
private
$databaseName
;
private
$databaseOptions
=
[];
private
$name
;
private
$name
;
private
$object
=
self
::
OBJECT_COLLECTION
;
private
$object
=
self
::
OBJECT_COLLECTION
;
...
@@ -101,6 +100,19 @@ final class Operation
...
@@ -101,6 +100,19 @@ final class Operation
return
$o
;
return
$o
;
}
}
public
static
function
fromCrud
(
stdClass
$operation
)
{
$o
=
new
self
(
$operation
);
$o
->
resultExpectation
=
ResultExpectation
::
fromCrud
(
$operation
,
$o
->
getResultAssertionType
());
if
(
isset
(
$operation
->
collectionOptions
))
{
$o
->
collectionOptions
=
(
array
)
$operation
->
collectionOptions
;
}
return
$o
;
}
public
static
function
fromRetryableWrites
(
stdClass
$operation
,
stdClass
$outcome
)
public
static
function
fromRetryableWrites
(
stdClass
$operation
,
stdClass
$outcome
)
{
{
$o
=
new
self
(
$operation
);
$o
=
new
self
(
$operation
);
...
@@ -122,10 +134,6 @@ final class Operation
...
@@ -122,10 +134,6 @@ final class Operation
$o
->
collectionOptions
=
(
array
)
$operation
->
collectionOptions
;
$o
->
collectionOptions
=
(
array
)
$operation
->
collectionOptions
;
}
}
if
(
isset
(
$operation
->
databaseOptions
))
{
$o
->
databaseOptions
=
(
array
)
$operation
->
databaseOptions
;
}
return
$o
;
return
$o
;
}
}
...
@@ -184,7 +192,7 @@ final class Operation
...
@@ -184,7 +192,7 @@ final class Operation
return
$this
->
executeForCollection
(
$collection
,
$context
);
return
$this
->
executeForCollection
(
$collection
,
$context
);
case
self
::
OBJECT_DATABASE
:
case
self
::
OBJECT_DATABASE
:
$database
=
$context
->
getDatabase
(
$this
->
databaseOptions
);
$database
=
$context
->
getDatabase
();
return
$this
->
executeForDatabase
(
$database
,
$context
);
return
$this
->
executeForDatabase
(
$database
,
$context
);
case
self
::
OBJECT_SELECT_COLLECTION
:
case
self
::
OBJECT_SELECT_COLLECTION
:
...
@@ -192,7 +200,7 @@ final class Operation
...
@@ -192,7 +200,7 @@ final class Operation
return
$this
->
executeForCollection
(
$collection
,
$context
);
return
$this
->
executeForCollection
(
$collection
,
$context
);
case
self
::
OBJECT_SELECT_DATABASE
:
case
self
::
OBJECT_SELECT_DATABASE
:
$database
=
$context
->
selectDatabase
(
$this
->
databaseName
,
$this
->
databaseOptions
);
$database
=
$context
->
selectDatabase
(
$this
->
databaseName
);
return
$this
->
executeForDatabase
(
$database
,
$context
);
return
$this
->
executeForDatabase
(
$database
,
$context
);
case
self
::
OBJECT_SESSION0
:
case
self
::
OBJECT_SESSION0
:
...
@@ -332,6 +340,12 @@ final class Operation
...
@@ -332,6 +340,12 @@ final class Operation
$context
->
replaceArgumentSessionPlaceholder
(
$args
);
$context
->
replaceArgumentSessionPlaceholder
(
$args
);
switch
(
$this
->
name
)
{
switch
(
$this
->
name
)
{
case
'aggregate'
:
return
$database
->
aggregate
(
$args
[
'pipeline'
],
array_diff_key
(
$args
,
[
'pipeline'
=>
1
])
);
case
'runCommand'
:
case
'runCommand'
:
return
$database
->
command
(
return
$database
->
command
(
$args
[
'command'
],
$args
[
'command'
],
...
@@ -453,6 +467,9 @@ final class Operation
...
@@ -453,6 +467,9 @@ final class Operation
private
function
getResultAssertionTypeForDatabase
()
private
function
getResultAssertionTypeForDatabase
()
{
{
switch
(
$this
->
name
)
{
switch
(
$this
->
name
)
{
case
'aggregate'
:
return
ResultExpectation
::
ASSERT_SAME_DOCUMENTS
;
case
'runCommand'
:
case
'runCommand'
:
return
ResultExpectation
::
ASSERT_MATCHES_DOCUMENT
;
return
ResultExpectation
::
ASSERT_MATCHES_DOCUMENT
;
...
...
tests/SpecTests/ResultExpectation.php
View file @
c2922d30
...
@@ -72,6 +72,19 @@ final class ResultExpectation
...
@@ -72,6 +72,19 @@ final class ResultExpectation
return
$o
;
return
$o
;
}
}
public
static
function
fromCrud
(
stdClass
$operation
,
$defaultAssertionType
)
{
if
(
property_exists
(
$operation
,
'result'
)
&&
!
self
::
isErrorResult
(
$operation
->
result
))
{
$assertionType
=
$operation
->
result
===
null
?
self
::
ASSERT_NULL
:
$defaultAssertionType
;
$expectedValue
=
$operation
->
result
;
}
else
{
$assertionType
=
self
::
ASSERT_NOTHING
;
$expectedValue
=
null
;
}
return
new
self
(
$assertionType
,
$expectedValue
);
}
public
static
function
fromRetryableWrites
(
stdClass
$outcome
,
$defaultAssertionType
)
public
static
function
fromRetryableWrites
(
stdClass
$outcome
,
$defaultAssertionType
)
{
{
if
(
property_exists
(
$outcome
,
'result'
))
{
if
(
property_exists
(
$outcome
,
'result'
))
{
...
...
tests/SpecTests/crud/aggregate-merge.json
0 → 100644
View file @
c2922d30
{
"runOn"
:
[
{
"minServerVersion"
:
"4.1.11"
}
],
"data"
:
[
{
"_id"
:
1
,
"x"
:
11
},
{
"_id"
:
2
,
"x"
:
22
},
{
"_id"
:
3
,
"x"
:
33
}
],
"collection_name"
:
"test_aggregate_merge"
,
"tests"
:
[
{
"description"
:
"Aggregate with $merge"
,
"operations"
:
[
{
"object"
:
"collection"
,
"name"
:
"aggregate"
,
"arguments"
:
{
"pipeline"
:
[
{
"$sort"
:
{
"x"
:
1
}
},
{
"$match"
:
{
"_id"
:
{
"$gt"
:
1
}
}
},
{
"$merge"
:
{
"into"
:
"other_test_collection"
}
}
]
}
}
],
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"aggregate"
:
"test_aggregate_merge"
,
"pipeline"
:
[
{
"$sort"
:
{
"x"
:
1
}
},
{
"$match"
:
{
"_id"
:
{
"$gt"
:
1
}
}
},
{
"$merge"
:
{
"into"
:
"other_test_collection"
}
}
]
}
}
}
],
"outcome"
:
{
"collection"
:
{
"name"
:
"other_test_collection"
,
"data"
:
[
{
"_id"
:
2
,
"x"
:
22
},
{
"_id"
:
3
,
"x"
:
33
}
]
}
}
},
{
"description"
:
"Aggregate with $merge and batch size of 0"
,
"operations"
:
[
{
"object"
:
"collection"
,
"name"
:
"aggregate"
,
"arguments"
:
{
"pipeline"
:
[
{
"$sort"
:
{
"x"
:
1
}
},
{
"$match"
:
{
"_id"
:
{
"$gt"
:
1
}
}
},
{
"$merge"
:
{
"into"
:
"other_test_collection"
}
}
],
"batchSize"
:
0
}
}
],
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"aggregate"
:
"test_aggregate_merge"
,
"pipeline"
:
[
{
"$sort"
:
{
"x"
:
1
}
},
{
"$match"
:
{
"_id"
:
{
"$gt"
:
1
}
}
},
{
"$merge"
:
{
"into"
:
"other_test_collection"
}
}
],
"cursor"
:
{}
}
}
}
],
"outcome"
:
{
"collection"
:
{
"name"
:
"other_test_collection"
,
"data"
:
[
{
"_id"
:
2
,
"x"
:
22
},
{
"_id"
:
3
,
"x"
:
33
}
]
}
}
},
{
"description"
:
"Aggregate with $merge and majority readConcern"
,
"operations"
:
[
{
"object"
:
"collection"
,
"name"
:
"aggregate"
,
"collectionOptions"
:
{
"readConcern"
:
{
"level"
:
"majority"
}
},
"arguments"
:
{
"pipeline"
:
[
{
"$sort"
:
{
"x"
:
1
}
},
{
"$match"
:
{
"_id"
:
{
"$gt"
:
1
}
}
},
{
"$merge"
:
{
"into"
:
"other_test_collection"
}
}
]
}
}
],
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"aggregate"
:
"test_aggregate_merge"
,
"pipeline"
:
[
{
"$sort"
:
{
"x"
:
1
}
},
{
"$match"
:
{
"_id"
:
{
"$gt"
:
1
}
}
},
{
"$merge"
:
{
"into"
:
"other_test_collection"
}
}
],
"readConcern"
:
{
"level"
:
"majority"
}
}
}
}
],
"outcome"
:
{
"collection"
:
{
"name"
:
"other_test_collection"
,
"data"
:
[
{
"_id"
:
2
,
"x"
:
22
},
{
"_id"
:
3
,
"x"
:
33
}
]
}
}
},
{
"description"
:
"Aggregate with $merge and local readConcern"
,
"operations"
:
[
{
"object"
:
"collection"
,
"name"
:
"aggregate"
,
"collectionOptions"
:
{
"readConcern"
:
{
"level"
:
"local"
}
},
"arguments"
:
{
"pipeline"
:
[
{
"$sort"
:
{
"x"
:
1
}
},
{
"$match"
:
{
"_id"
:
{
"$gt"
:
1
}
}
},
{
"$merge"
:
{
"into"
:
"other_test_collection"
}
}
]
}
}
],
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"aggregate"
:
"test_aggregate_merge"
,
"pipeline"
:
[
{
"$sort"
:
{
"x"
:
1
}
},
{
"$match"
:
{
"_id"
:
{
"$gt"
:
1
}
}
},
{
"$merge"
:
{
"into"
:
"other_test_collection"
}
}
],
"readConcern"
:
{
"level"
:
"local"
}
}
}
}
],
"outcome"
:
{
"collection"
:
{
"name"
:
"other_test_collection"
,
"data"
:
[
{
"_id"
:
2
,
"x"
:
22
},
{
"_id"
:
3
,
"x"
:
33
}
]
}
}
},
{
"description"
:
"Aggregate with $merge and available readConcern"
,
"operations"
:
[
{
"object"
:
"collection"
,
"name"
:
"aggregate"
,
"collectionOptions"
:
{
"readConcern"
:
{
"level"
:
"available"
}
},
"arguments"
:
{
"pipeline"
:
[
{
"$sort"
:
{
"x"
:
1
}
},
{
"$match"
:
{
"_id"
:
{
"$gt"
:
1
}
}
},
{
"$merge"
:
{
"into"
:
"other_test_collection"
}
}
]
}
}
],
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"aggregate"
:
"test_aggregate_merge"
,
"pipeline"
:
[
{
"$sort"
:
{
"x"
:
1
}
},
{
"$match"
:
{
"_id"
:
{
"$gt"
:
1
}
}
},
{
"$merge"
:
{
"into"
:
"other_test_collection"
}
}
],
"readConcern"
:
{
"level"
:
"available"
}
}
}
}
],
"outcome"
:
{
"collection"
:
{
"name"
:
"other_test_collection"
,
"data"
:
[
{
"_id"
:
2
,
"x"
:
22
},
{
"_id"
:
3
,
"x"
:
33
}
]
}
}
}
]
}
tests/SpecTests/crud/aggregate-out-readConcern.json
0 → 100644
View file @
c2922d30
{
"runOn"
:
[
{
"minServerVersion"
:
"4.1.0"
,
"topology"
:
[
"replicaset"
,
"sharded"
]
}
],
"data"
:
[
{
"_id"
:
1
,
"x"
:
11
},
{
"_id"
:
2
,
"x"
:
22
},
{
"_id"
:
3
,
"x"
:
33
}
],
"collection_name"
:
"test_aggregate_out_readconcern"
,
"tests"
:
[
{
"description"
:
"readConcern majority with out stage"
,
"operations"
:
[
{
"object"
:
"collection"
,
"name"
:
"aggregate"
,
"collectionOptions"
:
{
"readConcern"
:
{
"level"
:
"majority"
}
},
"arguments"
:
{
"pipeline"
:
[
{
"$sort"
:
{
"x"
:
1
}
},
{
"$match"
:
{
"_id"
:
{
"$gt"
:
1
}
}
},
{
"$out"
:
"other_test_collection"
}
]
}
}
],
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"aggregate"
:
"test_aggregate_out_readconcern"
,
"pipeline"
:
[
{
"$sort"
:
{
"x"
:
1
}
},
{
"$match"
:
{
"_id"
:
{
"$gt"
:
1
}
}
},
{
"$out"
:
"other_test_collection"
}
],
"readConcern"
:
{
"level"
:
"majority"
}
}
}
}
],
"outcome"
:
{
"collection"
:
{
"name"
:
"other_test_collection"
,
"data"
:
[
{
"_id"
:
2
,
"x"
:
22
},
{
"_id"
:
3
,
"x"
:
33
}
]
}
}
},
{
"description"
:
"readConcern local with out stage"
,
"operations"
:
[
{
"object"
:
"collection"
,
"name"
:
"aggregate"
,
"collectionOptions"
:
{
"readConcern"
:
{
"level"
:
"local"
}
},
"arguments"
:
{
"pipeline"
:
[
{
"$sort"
:
{
"x"
:
1
}
},
{
"$match"
:
{
"_id"
:
{
"$gt"
:
1
}
}
},
{
"$out"
:
"other_test_collection"
}
]
}
}
],
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"aggregate"
:
"test_aggregate_out_readconcern"
,
"pipeline"
:
[
{
"$sort"
:
{
"x"
:
1
}
},
{
"$match"
:
{
"_id"
:
{
"$gt"
:
1
}
}
},
{
"$out"
:
"other_test_collection"
}
],
"readConcern"
:
{
"level"
:
"local"
}
}
}
}
],
"outcome"
:
{
"collection"
:
{
"name"
:
"other_test_collection"
,
"data"
:
[
{
"_id"
:
2
,
"x"
:
22
},
{
"_id"
:
3
,
"x"
:
33
}
]
}
}
},
{
"description"
:
"readConcern available with out stage"
,
"operations"
:
[
{
"object"
:
"collection"
,
"name"
:
"aggregate"
,
"collectionOptions"
:
{
"readConcern"
:
{
"level"
:
"available"
}
},
"arguments"
:
{
"pipeline"
:
[
{
"$sort"
:
{
"x"
:
1
}
},
{
"$match"
:
{
"_id"
:
{
"$gt"
:
1
}
}
},
{
"$out"
:
"other_test_collection"
}
]
}
}
],
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"aggregate"
:
"test_aggregate_out_readconcern"
,
"pipeline"
:
[
{
"$sort"
:
{
"x"
:
1
}
},
{
"$match"
:
{
"_id"
:
{
"$gt"
:
1
}
}
},
{
"$out"
:
"other_test_collection"
}
],
"readConcern"
:
{
"level"
:
"available"
}
}
}
}
],
"outcome"
:
{
"collection"
:
{
"name"
:
"other_test_collection"
,
"data"
:
[
{
"_id"
:
2
,
"x"
:
22
},
{
"_id"
:
3
,
"x"
:
33
}
]
}
}
},
{
"description"
:
"readConcern linearizable with out stage"
,
"operations"
:
[
{
"object"
:
"collection"
,
"name"
:
"aggregate"
,
"collectionOptions"
:
{
"readConcern"
:
{
"level"
:
"linearizable"
}
},
"arguments"
:
{
"pipeline"
:
[
{
"$sort"
:
{
"x"
:
1
}
},
{
"$match"
:
{
"_id"
:
{
"$gt"
:
1
}
}
},
{
"$out"
:
"other_test_collection"
}
]
},
"error"
:
true
}
],
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"aggregate"
:
"test_aggregate_out_readconcern"
,
"pipeline"
:
[
{
"$sort"
:
{
"x"
:
1
}
},
{
"$match"
:
{
"_id"
:
{
"$gt"
:
1
}
}
},
{
"$out"
:
"other_test_collection"
}
],
"readConcern"
:
{
"level"
:
"linearizable"
}
}
}
}
]
},
{
"description"
:
"invalid readConcern with out stage"
,
"operations"
:
[
{
"object"
:
"collection"
,
"name"
:
"aggregate"
,
"collectionOptions"
:
{
"readConcern"
:
{
"level"
:
"!invalid123"
}
},
"arguments"
:
{
"pipeline"
:
[
{
"$sort"
:
{
"x"
:
1
}
},
{
"$match"
:
{
"_id"
:
{
"$gt"
:
1
}
}
},
{
"$out"
:
"other_test_collection"
}
]
},
"error"
:
true
}
],
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"aggregate"
:
"test_aggregate_out_readconcern"
,
"pipeline"
:
[
{
"$sort"
:
{
"x"
:
1
}
},
{
"$match"
:
{
"_id"
:
{
"$gt"
:
1
}
}
},
{
"$out"
:
"other_test_collection"
}
],
"readConcern"
:
{
"level"
:
"!invalid123"
}
}
}
}
]
}
]
}
tests/SpecTests/crud/bulkWrite-arrayFilters.json
0 → 100644
View file @
c2922d30
{
"runOn"
:
[
{
"minServerVersion"
:
"3.5.6"
}
],
"data"
:
[
{
"_id"
:
1
,
"y"
:
[
{
"b"
:
3
},
{
"b"
:
1
}
]
},
{
"_id"
:
2
,
"y"
:
[
{
"b"
:
0
},
{
"b"
:
1
}
]
}
],
"collection_name"
:
"test"
,
"database_name"
:
"crud-tests"
,
"tests"
:
[
{
"description"
:
"BulkWrite with arrayFilters"
,
"operations"
:
[
{
"name"
:
"bulkWrite"
,
"arguments"
:
{
"requests"
:
[
{
"name"
:
"updateOne"
,
"arguments"
:
{
"filter"
:
{},
"update"
:
{
"$set"
:
{
"y.$[i].b"
:
2
}
},
"arrayFilters"
:
[
{
"i.b"
:
3
}
]
}
},
{
"name"
:
"updateMany"
,
"arguments"
:
{
"filter"
:
{},
"update"
:
{
"$set"
:
{
"y.$[i].b"
:
2
}
},
"arrayFilters"
:
[
{
"i.b"
:
1
}
]
}
}
],
"options"
:
{
"ordered"
:
true
}
},
"result"
:
{
"deletedCount"
:
0
,
"insertedCount"
:
0
,
"insertedIds"
:
{},
"matchedCount"
:
3
,
"modifiedCount"
:
3
,
"upsertedCount"
:
0
,
"upsertedIds"
:
{}
}
}
],
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"update"
:
"test"
,
"updates"
:
[
{
"q"
:
{},
"u"
:
{
"$set"
:
{
"y.$[i].b"
:
2
}
},
"arrayFilters"
:
[
{
"i.b"
:
3
}
]
},
{
"q"
:
{},
"u"
:
{
"$set"
:
{
"y.$[i].b"
:
2
}
},
"multi"
:
true
,
"arrayFilters"
:
[
{
"i.b"
:
1
}
]
}
],
"ordered"
:
true
},
"command_name"
:
"update"
,
"database_name"
:
"crud-tests"
}
}
],
"outcome"
:
{
"collection"
:
{
"data"
:
[
{
"_id"
:
1
,
"y"
:
[
{
"b"
:
2
},
{
"b"
:
2
}
]
},
{
"_id"
:
2
,
"y"
:
[
{
"b"
:
0
},
{
"b"
:
2
}
]
}
]
}
}
}
]
}
tests/SpecTests/crud/db-aggregate.json
0 → 100644
View file @
c2922d30
{
"runOn"
:
[
{
"minServerVersion"
:
"3.6.0"
}
],
"database_name"
:
"admin"
,
"tests"
:
[
{
"description"
:
"Aggregate with $listLocalSessions"
,
"operations"
:
[
{
"name"
:
"aggregate"
,
"object"
:
"database"
,
"arguments"
:
{
"pipeline"
:
[
{
"$listLocalSessions"
:
{}
},
{
"$limit"
:
1
},
{
"$addFields"
:
{
"dummy"
:
"dummy field"
}
},
{
"$project"
:
{
"_id"
:
0
,
"dummy"
:
1
}
}
]
},
"result"
:
[
{
"dummy"
:
"dummy field"
}
]
}
]
},
{
"description"
:
"Aggregate with $listLocalSessions and allowDiskUse"
,
"operations"
:
[
{
"name"
:
"aggregate"
,
"object"
:
"database"
,
"arguments"
:
{
"pipeline"
:
[
{
"$listLocalSessions"
:
{}
},
{
"$limit"
:
1
},
{
"$addFields"
:
{
"dummy"
:
"dummy field"
}
},
{
"$project"
:
{
"_id"
:
0
,
"dummy"
:
1
}
}
],
"allowDiskUse"
:
true
},
"result"
:
[
{
"dummy"
:
"dummy field"
}
]
}
]
}
]
}
tests/SpecTests/crud/updateWithPipelines.json
0 → 100644
View file @
c2922d30
{
"data"
:
[
{
"_id"
:
1
,
"x"
:
1
,
"y"
:
1
,
"t"
:
{
"u"
:
{
"v"
:
1
}
}
},
{
"_id"
:
2
,
"x"
:
2
,
"y"
:
1
}
],
"minServerVersion"
:
"4.1.11"
,
"collection_name"
:
"test"
,
"database_name"
:
"crud-tests"
,
"tests"
:
[
{
"description"
:
"UpdateOne using pipelines"
,
"operations"
:
[
{
"name"
:
"updateOne"
,
"arguments"
:
{
"filter"
:
{
"_id"
:
1
},
"update"
:
[
{
"$replaceRoot"
:
{
"newRoot"
:
"$t"
}
},
{
"$addFields"
:
{
"foo"
:
1
}
}
]
},
"result"
:
{
"matchedCount"
:
1
,
"modifiedCount"
:
1
,
"upsertedCount"
:
0
}
}
],
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"update"
:
"test"
,
"updates"
:
[
{
"q"
:
{
"_id"
:
1
},
"u"
:
[
{
"$replaceRoot"
:
{
"newRoot"
:
"$t"
}
},
{
"$addFields"
:
{
"foo"
:
1
}
}
]
}
]
},
"command_name"
:
"update"
,
"database_name"
:
"crud-tests"
}
}
],
"outcome"
:
{
"collection"
:
{
"data"
:
[
{
"_id"
:
1
,
"u"
:
{
"v"
:
1
},
"foo"
:
1
},
{
"_id"
:
2
,
"x"
:
2
,
"y"
:
1
}
]
}
}
},
{
"description"
:
"UpdateMany using pipelines"
,
"operations"
:
[
{
"name"
:
"updateMany"
,
"arguments"
:
{
"filter"
:
{},
"update"
:
[
{
"$project"
:
{
"x"
:
1
}
},
{
"$addFields"
:
{
"foo"
:
1
}
}
]
},
"result"
:
{
"matchedCount"
:
2
,
"modifiedCount"
:
2
,
"upsertedCount"
:
0
}
}
],
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"update"
:
"test"
,
"updates"
:
[
{
"q"
:
{},
"u"
:
[
{
"$project"
:
{
"x"
:
1
}
},
{
"$addFields"
:
{
"foo"
:
1
}
}
],
"multi"
:
true
}
]
},
"command_name"
:
"update"
,
"database_name"
:
"crud-tests"
}
}
],
"outcome"
:
{
"collection"
:
{
"data"
:
[
{
"_id"
:
1
,
"x"
:
1
,
"foo"
:
1
},
{
"_id"
:
2
,
"x"
:
2
,
"foo"
:
1
}
]
}
}
},
{
"description"
:
"FindOneAndUpdate using pipelines"
,
"operations"
:
[
{
"name"
:
"findOneAndUpdate"
,
"arguments"
:
{
"filter"
:
{
"_id"
:
1
},
"update"
:
[
{
"$project"
:
{
"x"
:
1
}
},
{
"$addFields"
:
{
"foo"
:
1
}
}
]
}
}
],
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"findAndModify"
:
"test"
,
"update"
:
[
{
"$project"
:
{
"x"
:
1
}
},
{
"$addFields"
:
{
"foo"
:
1
}
}
]
},
"command_name"
:
"findAndModify"
,
"database_name"
:
"crud-tests"
}
}
],
"outcome"
:
{
"collection"
:
{
"data"
:
[
{
"_id"
:
1
,
"x"
:
1
,
"foo"
:
1
},
{
"_id"
:
2
,
"x"
:
2
,
"y"
:
1
}
]
}
}
}
]
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment