diff --git a/source/test/cxx-connection-pools.txt b/source/test/cxx-connection-pools.txt new file mode 100644 index 000000000..b8b0573e9 --- /dev/null +++ b/source/test/cxx-connection-pools.txt @@ -0,0 +1,62 @@ + ++++ +date = "2017-04-18 13:39:39-04:00" +title = "Connection pools" +[menu.main] + weight = 15 + parent="mongocxx3" ++++ + +``mongocxx::client`` vs ``mongocxx::pool`` +-------------------------------------------------- + +A standalone ``mongocxx::client`` uses a single-threaded algorithm to +monitor the state of the cluster it's connected to. When connected to a +replica set, the thread "stops the world" every 60 seconds to check the +status of the cluster. A ``mongocxx::pool``\ , on the other hand, uses a +separate background thread for each server in the cluster, each of which +checks the status of the server it monitors every 10 seconds. Because of +the performance advantages of monitoring the cluster in the background +rather than "stopping the world", it's highly recommended to use a +``mongocxx::pool`` rather than a set of standalone clients if your +application has access to multiple threads, even if your application only +uses one thread. + +Connection pools and thread safety +---------------------------------- + +A ``mongocxx::pool`` can be shared across multiple threads and used to create +clients. However, each ``mongocxx::client`` can only be used in a single +thread. See the `thread safety documentation <../thread-safety/>`__ for +details on how to use a ``mongocxx::client`` in a thread-safe manner. + +Configuring a connection pool +----------------------------- + +The number of clients in a connection pool is determined by the URI +parameters ``minPoolSize`` and ``maxPoolSize``. The ``minPoolSize`` and +``maxPoolSize`` options set resource usage targets for when the driver is +idle or fully-utilized. When fully utilized, up to maxPoolSize clients +are available. When clients are returned to the pool, they are destroyed +until the pool has shrunk again to the minPoolSize. + +.. list-table:: + :header-rows: 1 + + * - ‌‌ + * - maxPoolSize + - The maximum number of clients created by a mongocxx::pool (both in the pool and checked out). The default value is 100. Once it is reached, mongocxx::pool::acquire blocks until another thread returns a client to the pool. + * - minPoolSize + - Sets a target size for the pool when idle. Once this many clients have been created, there will never be fewer than this many clients in the pool. If additional clients above minPoolSize are created, they will be destroyed when returned to the pool. The default value is "0", which disables this feature. When disabled, clients are never destroyed. + + +Using a connection pool +----------------------- + +To use a connection pool, first create a ``mongocxx::pool``\ , passing the URI +as an argument. Then, call ``mongocxx::pool::acquire`` to receive a client +from the pool. The client will automatically be returned to the pool when +it goes out of scope. + +See the `connection pool example `__ +for more details. diff --git a/source/test/cxx-installation-index.txt b/source/test/cxx-installation-index.txt new file mode 100644 index 000000000..ac3148854 --- /dev/null +++ b/source/test/cxx-installation-index.txt @@ -0,0 +1,173 @@ + ++++ +date = "2020-09-26T13:14:52-04:00" +title = "Installing the mongocxx driver" +[menu.main] + identifier = "mongocxx3-installation" + parent = "mongocxx3" + weight = 8 ++++ + +Prerequisites +------------- + + +* Any standard Unix platform, or Windows 7 SP1+ +* A compiler that supports C++11 (gcc, clang, or Visual Studio) +* `CMake `__ 3.2 or later +* `boost `__ headers (optional) + +If you encounter build failures or other problems with a platform configuration +that meets the above prerequisites, please file a bug report via +`JIRA `__. + +Installation +------------ + +To configure and install the driver, follow the instructions for your platform: + + +* `Configuring and installing on Windows <{{< ref "/mongocxx-v3/installation/windows" >}}>`__ +* `Configuring and installing on macOS <{{< ref "/mongocxx-v3/installation/macos" >}}>`__ +* `Configuring and installing on Linux <{{< ref "/mongocxx-v3/installation/linux" >}}>`__ + +Advanced Options +---------------- + + +* `Advanced Configuration and Installation Options <{{< ref "/mongocxx-v3/installation/advanced" >}}>`__ + +Package Managers +---------------- + +The Mongo C++ driver is available in the following package managers. + + +* `Vcpkg `__ (search for mongo-cxx-driver) +* `Conan `__ +* `Homebrew `__ + +Vcpkg Install Instructions +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you do not already have Vcpkg installed, install it with the following +command: + +.. code-block:: + + $ git clone https://github.com/Microsoft/vcpkg.git + $ cd vcpkg + $ ./bootstrap-vcpkg.sh + +Optionally, to install with Visual Studio integration: + +.. code-block:: + + vcpkg integrate install + +Install the driver. (You may need to ``git pull`` to get the latest version of the +driver) + +.. code-block:: + + $ ./vcpkg install mongo-cxx-driver + +You can use the toolchain file, ``vcpkg.cmake``\ , to instruct CMake where to find +the development files, for example: + +.. code-block:: + + -DCMAKE_TOOLCHAIN_FILE=//vcpkg/scripts/buildsystems/vcpkg.cmake + +You can find the header files in: + +.. code-block:: + + vcpkg/installed/-/include/ + +The library files are in: + +.. code-block:: + + vcpkg/installed/-/lib/ + +Conan Install Instructions +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Package Specifier: ``mongo-cxx-driver/3.8.0`` + +If you do not already have Conan installed, then install it and run the Conan +initalization command below: + +.. code-block:: + + $ pip install conan + $ conan profile detect --force + +Add the following to your ``conanfile.txt`` + +.. code-block:: + + [requires] + mongo-cxx-driver/3.8.0 + [generators] + CMakeDeps + CMakeToolchain + +Install the driver via Conan, and build your project: + +.. code-block:: + + $ conan install conanfile.txt --output-folder=build --build=missing + $ cmake \ + -B build \ + -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake \ + -DCMAKE_BUILD_TYPE=Release + $ cmake --build build + +Homebrew +~~~~~~~~ + +For MacOS users, homebrew is a convienent way to install the C++ driver. + +.. code-block:: + + brew install mongo-cxx-driver + +For an Apple Silicon Mac +```````````````````````` + +Headers can be found in: + +.. code-block:: + + /opt/homebrew/include/mongocxx/v_noabi/ + /opt/homebrew/include/bsoncxx/v_noabi/ + +Library files can be found in: + +.. code-block:: + + /opt/homebrew/lib/ + +For an Intel Mac +```````````````` + +Headers can be found in: + +.. code-block:: + + /usr/local/include/mongocxx/v_noabi/ + /usr/local/include/bsoncxx/v_noabi/ + +Library files can be found in: + +.. code-block:: + + /usr/local/lib/ + +Docker Image +------------ + +You can find a pre-built docker image for the C++ driver in +`Docker Hub `__. diff --git a/source/test/cxx-tutorial.txt b/source/test/cxx-tutorial.txt new file mode 100644 index 000000000..9d4799531 --- /dev/null +++ b/source/test/cxx-tutorial.txt @@ -0,0 +1,494 @@ + ++++ +date = "2016-08-15T16:11:58+05:30" +title = "Tutorial for mongocxx" +[menu.main] + identifier = 'mongocxx-tutorial' + weight = 11 + parent="mongocxx3" ++++ + +See the full code for this tutorial in +`tutorial.cpp `__. + +Prerequisites +------------- + + +* + A `mongod `__ + instance running on localhost on port 27017. + +* + The mongocxx Driver. See `Installation for mongocxx <{{< ref "/mongocxx-v3/installation" >}}>`__. + +* + The following statements at the top of your source file: + +.. code-block:: c++ + + #include + #include + #include + + #include + #include + #include + #include + #include + #include + + using bsoncxx::builder::basic::kvp; + using bsoncxx::builder::basic::make_array; + using bsoncxx::builder::basic::make_document; + +Compiling +--------- + +The mongocxx driver's installation process will install a +``libmongocxx.pc`` file for use +with `pkg-config `__. + +To compile a program, run the following command: + +.. code-block:: sh + + c++ --std=c++11 .cpp $(pkg-config --cflags --libs libmongocxx) + +If you don't have pkg-config available, you will need to set include and +library flags manually on the command line or in your IDE. For example, if +libmongoc and mongocxx are installed in ``/usr/local``\ , then the compilation +line in above expands to this: + +.. code-block:: sh + + c++ --std=c++11 .cpp + -I/usr/local/include/mongocxx/v_noabi \ + -I/usr/local/include/bsoncxx/v_noabi \ + -L/usr/local/lib -lmongocxx -lbsoncxx + +Make a Connection +----------------- + +**IMPORTANT**\ : Before making any connections, you need to create one and only +one instance of `\ ``mongocxx::instance`` <{{< api3ref classmongocxx_1_1instance >}}>`__. +This instance must exist for the entirety of your program. + +To connect to a running MongoDB instance, use the +`\ ``mongocxx::client`` <{{< api3ref classmongocxx_1_1client >}}>`__ +class. + +You must specify the host to connect to using a +`\ ``mongocxx::uri`` <{{< api3ref classmongocxx_1_1uri >}}>`__ instance containing a +`MongoDB URI `__\ , +and pass that into the ``mongocxx::client`` constructor. For details regarding +supported URI options see the documentation for the version of libmongoc used +to build the C++ driver or for the `latest libmongoc release `__ + +The default ``mongocxx::uri`` constructor will connect to a +server running on localhost on port ``27017``\ : + +.. code-block:: c++ + + mongocxx::instance instance{}; // This should be done only once. + mongocxx::client client{mongocxx::uri{}}; + +This is equivalent to the following: + +.. code-block:: c++ + + mongocxx::instance instance{}; // This should be done only once. + mongocxx::uri uri("mongodb://localhost:27017"); + mongocxx::client client(uri); + +Access a Database +----------------- + +Once you have a `\ ``mongocxx::client`` <{{< api3ref classmongocxx_1_1client >}}>`__ +instance connected to a MongoDB deployment, use either the +``database()`` method or ``operator[]`` to obtain a +`\ ``mongocxx::database`` <{{< api3ref classmongocxx_1_1database >}}>`__ +instance. + +If the database you request does not exist, MongoDB creates it when you +first store data. + +The following example accesses the ``mydb`` database: + +.. code-block:: c++ + + auto db = client["mydb"]; + +Access a Collection +------------------- + +Once you have a +`\ ``mongocxx::database`` <{{< api3ref classmongocxx_1_1database >}}>`__ +instance, use either the ``collection()`` method or ``operator[]`` to obtain a +`\ ``mongocxx::collection`` <{{< api3ref classmongocxx_1_1collection >}}>`__ +instance. + +If the collection you request does not exist, MongoDB creates it when +you first store data. + +For example, using the ``db`` instance created in the previous section, +the following statement accesses the collection named ``test`` in the +``mydb`` database: + +.. code-block:: c++ + + auto collection = db["test"]; + +Create a Document +----------------- + +To create a ``document`` using the C++ driver, use one of the two +available builder interfaces: + +Stream builder: ``bsoncxx::builder::stream`` + A document builder using the streaming operators that works well for + literal document construction. + +Basic builder: ``bsoncxx::builder::basic`` + A more conventional document builder that involves calling methods on + a builder instance. + +This guide only briefly describes the basic builder. + +For example, consider the following JSON document: + +.. code-block:: json + + { + "name" : "MongoDB", + "type" : "database", + "count" : 1, + "versions": [ "v6.0", "v5.0", "v4.4", "v4.2", "v4.0", "v3.6" ], + "info" : { + "x" : 203, + "y" : 102 + } + } + +Using the basic builder interface, you can construct this document +as follows: + +.. code-block:: c++ + + auto doc_value = make_document( + kvp("name", "MongoDB"), + kvp("type", "database"), + kvp("count", 1), + kvp("versions", make_array("v6.0", "v5.0", "v4.4", "v4.2", "v4.0", "v3.6")), + kvp("info", make_document(kvp("x", 203), kvp("y", 102)))); + +This ``bsoncxx::document::value`` type is a read-only object owning +its own memory. To use it, you must obtain a +`\ ``bsoncxx::document::view`` <{{< api3ref classbsoncxx_1_1document_1_1view >}}>`__ using +the ``view()`` method: + +.. code-block:: c++ + + auto doc_view = doc_value.view(); + +You can access fields within this document view using ``operator[]``\ , +which will return a +`\ ``bsoncxx::document::element`` <{{< api3ref classbsoncxx_1_1document_1_1element >}}>`__ +instance. For example, the following will extract the ``name`` field whose +value is a string: + +.. code-block:: c++ + + auto element = doc_view["name"]; + assert(element.type() == bsoncxx::type::k_string); + auto name = element.get_string().value; // For C++ driver version < 3.7.0, use get_utf8() + assert(0 == name.compare("MongoDB")); + +If the value in the ``name`` field is not a string and you do not +include a type guard as seen in the preceding example, this code will +throw an instance of +`\ ``bsoncxx::exception`` <{{< api3ref classbsoncxx_1_1exception >}}>`__. + +Insert Documents +---------------- + +Insert One Document +~~~~~~~~~~~~~~~~~~~ + +To insert a single document into the collection, use a +`\ ``mongocxx::collection`` <{{< api3ref classmongocxx_1_1collection >}}>`__ +instance's ``insert_one()`` method to insert ``{ "i": 0 }``\ : + +.. code-block:: c++ + + auto insert_one_result = collection.insert_one(make_document(kvp("i", 0))); + +``insert_one_result`` is an optional `\ ``mongocxx::result::insert_one`` <{{< api3ref +classmongocxx_1_1result_1_1insert_one >}}>`__. In this example, ``insert_one_result`` +is expected to be set. The default behavior for write operations is to wait for +a reply from the server. This may be overriden by setting an unacknowledged +`\ ``mongocxx::write_concern`` <{{< api3ref classmongocxx_1_1write__concern >}}>`__. + +.. code-block:: c++ + + assert(insert_one_result); // Acknowledged writes return results. + +If you do not specify a top-level ``_id`` field in the document, +MongoDB automatically adds an ``_id`` field to the inserted document. + +You can obtain this value using the ``inserted_id()`` method of the +returned +`\ ``mongocxx::result::insert_one`` <{{< api3ref classmongocxx_1_1result_1_1insert__one >}}>`__ +instance. + +.. code-block:: c++ + + auto doc_id = insert_one_result->inserted_id(); + assert(doc_id.type() == bsoncxx::type::k_oid); + +Insert Multiple Documents +~~~~~~~~~~~~~~~~~~~~~~~~~ + +To insert multiple documents to the collection, use a +`\ ``mongocxx::collection`` <{{< api3ref classmongocxx_1_1collection >}}>`__ instance's +``insert_many()`` method, which takes a list of documents to insert. + +The following example inserts the documents ``{ "i": 1 }`` and ``{ "i": 2 }``. +Create the documents and add to the documents list: + +.. code-block:: c++ + + std::vector documents; + documents.push_back(make_document(kvp("i", 1))); + documents.push_back(make_document(kvp("i", 2))); + +To insert these documents to the collection, pass the list of documents +to the ``insert_many()`` method. + +.. code-block:: c++ + + auto insert_many_result = collection.insert_many(documents); + assert(insert_many_result); // Acknowledged writes return results. + +If you do not specify a top-level ``_id`` field in each document, +MongoDB automatically adds a ``_id`` field to the inserted documents. + +You can obtain this value using the ``inserted_ids()`` method of the +returned +`\ ``mongocxx::result::insert_many`` <{{< api3ref classmongocxx_1_1result_1_1insert__many >}}>`__ +instance. + +.. code-block:: c++ + + auto doc0_id = insert_many_result->inserted_ids().at(0); + auto doc1_id = insert_many_result->inserted_ids().at(1); + assert(doc0_id.type() == bsoncxx::type::k_oid); + assert(doc1_id.type() == bsoncxx::type::k_oid); + +Query the Collection +-------------------- + +To query the collection, use the collection’s ``find()`` and +``find_one`` methods. + +``find()`` will return an instance of +`\ ``mongocxx::cursor`` <{{< api3ref classmongocxx_1_1cursor >}}>`__\ , +while ``find_one()`` will return an instance of +``std::optional<``\ `\ ``bsoncxx::document::value`` <{{< api3ref classbsoncxx_1_1document_1_1value >}}>`__\ ``>`` + +You can call either method with an empty document to query all documents +in a collection, or pass a filter to query for documents that match the +filter criteria. + +Find a Single Document in a Collection +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To return a single document in the collection, use the ``find_one()`` +method without any parameters. + +.. code-block:: c++ + + auto find_one_result = collection.find_one({}); + if (find_one_result) { + // Do something with *find_one_result + } + assert(find_one_result); + +Find All Documents in a Collection +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: c++ + + auto cursor_all = collection.find({}); + for (auto doc : cursor_all) { + // Do something with doc + assert(doc["_id"].type() == bsoncxx::type::k_oid); + } + +Print All Documents in a Collection +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The `\ ``bsoncxx::to_json`` <{{< api3ref namespacebsoncxx>}}>`__ function converts a BSON document to a JSON string. + +.. code-block:: c++ + + auto cursor_all = collection.find({}); + std::cout << "collection " << collection.name() + << " contains these documents:" << std::endl; + for (auto doc : cursor_all) { + std::cout << bsoncxx::to_json(doc, bsoncxx::ExtendedJsonMode::k_relaxed) << std::endl; + } + std::cout << std::endl; + +The above example prints output resembling the following: + +.. code-block:: + + collection test contains these documents: + { "_id" : { "$oid" : "6409edb48c37f371c70f03a1" }, "i" : 0 } + { "_id" : { "$oid" : "6409edb48c37f371c70f03a2" }, "i" : 1 } + { "_id" : { "$oid" : "6409edb48c37f371c70f03a3" }, "i" : 2 } + +The ``_id`` element has been added automatically by MongoDB to your +document and your value will differ from that shown. MongoDB reserves +field names that start with an underscore (\ ``_``\ ) and the dollar sign +(\ ``$``\ ) for internal use. + +Specify a Query Filter +~~~~~~~~~~~~~~~~~~~~~~ + +Get A Single Document That Matches a Filter +``````````````````````````````````````````` + +To find the first document where the field ``i`` has the value ``0``\ , +pass the document ``{"i": 0}`` to specify the equality condition: + +.. code-block:: c++ + + auto find_one_filtered_result = collection.find_one(make_document(kvp("i", 0))); + if (find_one_filtered_result) { + // Do something with *find_one_filtered_result + } + +Get All Documents That Match a Filter +````````````````````````````````````` + +The following example gets all documents where ``0 < "i" <= 2``\ : + +.. code-block:: c++ + + auto cursor_filtered = + collection.find(make_document(kvp("i", make_document(kvp("$gt", 0), kvp("$lte", 2))))); + for (auto doc : cursor_filtered) { + // Do something with doc + assert(doc["_id"].type() == bsoncxx::type::k_oid); + } + +Update Documents +---------------- + +To update documents in a collection, you can use the collection’s +``update_one()`` and ``update_many()`` methods. + +The update methods return an instance of +``std::optional<``\ `\ ``mongocxx::result::update`` <{{< api3ref classmongocxx_1_1result_1_1update >}}>`__\ ``>``\ , +which provides information about the operation including the number of +documents modified by the update. + +Update a Single Document +~~~~~~~~~~~~~~~~~~~~~~~~ + +To update at most one document, use the ``update_one()`` method. + +The following example updates the first document that matches the filter +``{ "i": 0 }`` and sets the value of ``foo`` to ``bar``\ : + +.. code-block:: c++ + + auto update_one_result = + collection.update_one(make_document(kvp("i", 0)), + make_document(kvp("$set", make_document(kvp("foo", "bar"))))); + assert(update_one_result); // Acknowledged writes return results. + assert(update_one_result->modified_count() == 1); + +Update Multiple Documents +~~~~~~~~~~~~~~~~~~~~~~~~~ + +To update all documents matching a filter, use the ``update_many()`` +method. + +The following example sets the value of ``foo`` to ``buzz`` where +``i`` is greater than ``0``\ : + +.. code-block:: c++ + + auto update_many_result = + collection.update_many(make_document(kvp("i", make_document(kvp("$gt", 0)))), + make_document(kvp("$set", make_document(kvp("foo", "buzz"))))); + assert(update_many_result); // Acknowledged writes return results. + assert(update_many_result->modified_count() == 2); + +Delete Documents +---------------- + +To delete documents from a collection, you can use a collection’s +``delete_one()`` and ``delete_many()`` methods. + +The delete methods return an instance of +``std::optional<``\ `\ ``mongocxx::result::delete`` <{{< api3ref classmongocxx_1_1result_1_1delete__result >}}>`__\ ``>``\ , +which contains the number of documents deleted. + +Delete a Single Document +~~~~~~~~~~~~~~~~~~~~~~~~ + +To delete at most a single document that matches a filter, use the +``delete_one()`` method. + +For example, to delete a document that matches the filter +``{ "i": 0 }``\ : + +.. code-block:: c++ + + auto delete_one_result = collection.delete_one(make_document(kvp("i", 0))); + assert(delete_one_result); // Acknowledged writes return results. + assert(delete_one_result->deleted_count() == 1); + +Delete All Documents That Match a Filter +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To delete all documents matching a filter, use a collection's +``delete_many()`` method. + +The following example deletes all documents where ``i`` is greater than ``0``\ : + +.. code-block:: c++ + + auto delete_many_result = + collection.delete_many(make_document(kvp("i", make_document(kvp("$gt", 0))))); + assert(delete_many_result); // Acknowledged writes return results. + assert(delete_many_result->deleted_count() == 2); + +Create Indexes +-------------- + +To create an `index `__ on a +field or set of fields, pass an index specification document to the +``create_index()`` method of a +`\ ``mongocxx::collection`` <{{< api3ref classmongocxx_1_1collection >}}>`__ instance. An +index key specification document contains the fields to index and the +index type for each field: + +.. code-block:: json + + { "index1": "", "index2": "" } + + +* For an ascending index type, specify 1 for ````. +* For a descending index type, specify -1 for ````. + +The following example creates an ascending index on the ``i`` field: + +.. code-block:: c++ + + auto index_specification = make_document(kvp("i", 1)); + collection.create_index(std::move(index_specification)); diff --git a/source/test/java-drivers-aggregation.txt b/source/test/java-drivers-aggregation.txt new file mode 100644 index 000000000..4e7776989 --- /dev/null +++ b/source/test/java-drivers-aggregation.txt @@ -0,0 +1,119 @@ + ++++ +date = "2016-06-08T14:19:24-04:00" +title = "Aggregation" +[menu.main] +parent = "Sync Tutorials" +identifier = "Aggregation" +weight = 50 +pre = "" ++++ + +Aggregation Framework +--------------------- + +The `aggregation pipeline <{{}}>`__ is a framework for data aggregation, modeled on the concept of data processing pipelines. + +Prerequisites +------------- + + +* + The example below requires a ``restaurants`` collection in the ``test`` database. To create and populate the collection, follow the directions in `github `__. + +* + Include the following import statements: + + .. code-block:: java + + import com.mongodb.client.MongoClients; + import com.mongodb.client.MongoClient; + import com.mongodb.client.MongoCollection; + import com.mongodb.client.MongoDatabase; + import com.mongodb.client.model.Aggregates; + import com.mongodb.client.model.Accumulators; + import com.mongodb.client.model.Projections; + import com.mongodb.client.model.Filters; + + import org.bson.Document; + +Connect to a MongoDB Deployment +------------------------------- + +Connect to a MongoDB deployment and declare and define a ``MongoDatabase`` and a ``MongoCollection`` instances. + +For example, include the following code to connect to a standalone MongoDB deployment running on localhost on port ``27017`` and define ``database`` to refer to the ``test`` database and ``collection`` to refer to the ``restaurants`` collection. + +.. code-block:: java + + MongoClient mongoClient = MongoClients.create(); + MongoDatabase database = mongoClient.getDatabase("test"); + MongoCollection collection = database.getCollection("restaurants"); + +For additional information on connecting to MongoDB, see `Connect to MongoDB <{{< ref "connect-to-mongodb.md" >}}>`__. + +Perform Aggregation +------------------- + +To perform aggregation, pass a list of `aggregation stages <{{< docsref "meta/aggregation-quick-reference" >}}>`__ to the `\ ``MongoCollection.aggregate()`` <{{< apiref "mongodb-driver-sync" "com/mongodb/client/MongoCollection.html#aggregate(java.util.List>`__\ " >}}) method. +The Java driver provides the `\ ``Aggregates`` <{{< apiref "mongodb-driver-core" "com/mongodb/client/model/Aggregates.html" >}}>`__ helper class that contains builders for aggregation stages. + +In the following example, the aggregation pipeline + + +* + First uses a `\ ``$match`` <{{< docsref "reference/operator/aggregation/match/" >}}>`__ stage to filter for documents whose ``categories`` array field contains the element ``Bakery``. The example uses `\ ``Aggregates.match`` <{{< relref "builders/aggregation.md#match" >}}>`__ to build the ``$match`` stage. + +* + Then, uses a `\ ``$group`` <{{< docsref "reference/operator/aggregation/group/" >}}>`__ stage to group the matching documents by the ``stars`` field, accumulating a count of documents for each distinct value of ``stars``. The example uses `\ ``Aggregates.group`` <{{< relref "builders/aggregation.md#group" >}}>`__ to build the ``$group`` stage and `\ ``Accumulators.sum`` <{{< apiref "mongodb-driver-core" "com/mongodb/client/model/Accumulators#sum(java.lang.String,TExpression>`__\ " >}}) to build the `accumulator expression <{{< docsref "reference/operator/aggregation/group/#accumulator-operator" >}}>`__. For the `accumulator expressions <{{< docsref "reference/operator/aggregation-group/" >}}>`__ for use within the `\ ``$group`` <{{< docsref "reference/operator/aggregation/group/" >}}>`__ stage, the Java driver provides `\ ``Accumulators`` <{{< apiref "mongodb-driver-core" "com/mongodb/client/model/Accumulators.html" >}}>`__ helper class. + + .. code-block:: java + + collection.aggregate( + Arrays.asList( + Aggregates.match(Filters.eq("categories", "Bakery")), + Aggregates.group("$stars", Accumulators.sum("count", 1)) + ) + ).forEach(doc -> System.out.println(doc.toJson())); + +Use Aggregation Expressions +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For `$group accumulator expressions <{{< docsref "reference/operator/aggregation-group/" >}}>`__\ , the Java driver provides `\ ``Accumulators`` <{{< apiref "mongodb-driver-core" "com/mongodb/client/model/Accumulators.html" >}}>`__ helper class. For other `aggregation expressions <{{< docsref "meta/aggregation-quick-reference/#aggregation-expressions" >}}>`__\ , manually build the expression ``Document``. + +In the following example, the aggregation pipeline uses a `\ ``$project`` <{{< docsref "reference/operator/aggregation/project/" >}}>`__ stage to return only the ``name`` field and the calculated field ``firstCategory`` whose value is the first element in the ``categories`` array. The example uses `\ ``Aggregates.project`` <{{< relref "builders/aggregation.md#project" >}}>`__ and various +`\ ``Projections`` <{{< apiref "mongodb-driver-core" "com/mongodb/client/model/Projections.html" >}}>`__ methods to build the ``$project`` stage. + +.. code-block:: java + + collection.aggregate( + Arrays.asList( + Aggregates.project( + Projections.fields( + Projections.excludeId(), + Projections.include("name"), + Projections.computed( + "firstCategory", + new Document("$arrayElemAt", Arrays.asList("$categories", 0)) + ) + ) + ) + ) + ).forEach(doc -> System.out.println(doc.toJson())); + +Explain an Aggregation +~~~~~~~~~~~~~~~~~~~~~~ + +To `explain <{{< docsref "reference/command/explain/" >}}>`__ an aggregation pipeline, call the +`\ ``AggregateIterable.explain()`` <{{< apiref "mongodb-driver-sync" "com/mongodb/client/AggregateIterable.html#explain(>`__\ " >}}) method: + +.. code-block:: java + + Document explainResult = collection.aggregate( + Arrays.asList( + Aggregates.match(Filters.eq("categories", "Bakery")), + Aggregates.group("$stars", Accumulators.sum("count", 1)))) + .explain(); + System.out.println(explainResult.toJson(JsonWriterSettings.builder().indent(true).build())); + +The driver supports explain of aggregation pipelines starting with MongoDB 3.6. diff --git a/source/test/java-drivers-index.txt b/source/test/java-drivers-index.txt new file mode 100644 index 000000000..767b2a3ea --- /dev/null +++ b/source/test/java-drivers-index.txt @@ -0,0 +1,43 @@ + ++++ +date = "2015-03-17T15:36:56Z" +title = "index" +type = "index" ++++ + +MongoDB Java Driver Documentation +--------------------------------- + +Welcome to the MongoDB JVM driver documentation hub. Please note that the primary documentation is now located `on the MongoDB domain `__ + +What's New +~~~~~~~~~~ + +For key new features, see `What's New <{{< relref "whats-new.md" >}}>`__. + +Upgrade +~~~~~~~ + +To upgrade, refer to the `Upgrade Considerations <{{< relref "upgrading.md" >}}>`__ documentation. + +MongoDB Driver +~~~~~~~~~~~~~~ + +For the synchronous MongoDB Driver, see `MongoDB Driver section <{{< relref "driver/index.md" >}}>`__. + +MongoDB Reactive Streams Driver +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For the MongoDB Reactive Streams Driver, see `MongoDB Reactive Streams Driver section <{{< relref "driver-reactive/index.md" >}}>`__. + +MongoDB Scala Driver +~~~~~~~~~~~~~~~~~~~~ + +For the MongoDB Scala Driver, see `MongoDB Scala Driver section <{{< relref "driver-scala/index.md" >}}>`__. + +BSON Library +~~~~~~~~~~~~ + +The `BSON <{{< relref "bson/index.md" >}}>`__ library comprehensively supports the BSON spec, the data storage and network transfer format that MongoDB uses for +“documents". The `reference guide <{{< relref "bson/index.md" >}}>`__ provides information about working with `Documents <{{< relref "bson/documents.md" >}}>`__\ , +how to use `Codecs <{{< relref "bson/codecs.md" >}}>`__ and `Extended JSON <{{< relref "bson/extended-json.md" >}}>`__ support. diff --git a/source/test/java-drivers-what-new.txt b/source/test/java-drivers-what-new.txt new file mode 100644 index 000000000..e539411b5 --- /dev/null +++ b/source/test/java-drivers-what-new.txt @@ -0,0 +1,675 @@ + ++++ +date = "2016-06-09T12:47:43-04:00" +title = "What's New" +[menu.main] + identifier = "Release notes" + weight = 15 + pre = "" ++++ + +For versions 4.5 and later, refer to the `What's New - Java Sync Documentation `__. + +================= +What's new in 4.4 +================= + + +* Compatibility with MongoDB 5.1 and support for Java 17 +* Added support for index hints in an AggregateIterable +* Added support for the $merge and $out aggregation stages on secondaries +* Use of the ``mergeObjects()`` method in the Updates builder +* DocumentCodec does not ignore a CodecRegistry when writing to an Iterable or a Map instance + +================= +What's new in 4.3 +================= + +This release fully supports all MongoDB releases from versions 2.6 to 4.4. It also supports some features of the next release of MongoDB. + +New features of the 4.3 Java driver release include: + + +* Added support for the MongoDB Versioned API. See the + `\ ``ServerApi`` <{{< apiref "mongodb-driver-core" "com/mongodb/ServerApi.html" >}}>`__ API documentation for details. +* Removed most restrictions on allowed characters in field names of documents being inserted or replaced. This is a behavioral change + for any application that is relying on client-side enforcement of these restrictions. In particular: + + * Restrictions on field names containing the "." character have been removed. This affects all insert and replace operations. + * Restrictions on field names starting with the "$" character have been removed for all insert operations. + * Restrictions in nested documents on field names starting with the "$" character have been removed for all replace operations. + * Restrictions in the top-level document on field names starting with the "$" character remain for all replace operations. This is + primarily to prevent accidental use of a replace operation when the intention was to use an update operation. + * Note that unacknowledged writes using dollar-prefixed or dotted keys may be silently rejected by pre-5.0 servers, where some + restrictions on field names are still enforced in the server. + +* Added support for setting + `Netty `__ `\ ``io.netty.handler.ssl.SslContext`` <{{< nettyapiref "io/netty/handler/ssl/SslContext.html" >}}>`__\ , + which may be used as a convenient way to utilize `OpenSSL `__ as an alternative + to the TLS/SSL protocol implementation in a JDK. +* Added `builders <{{< apiref "mongodb-driver-core" "com/mongodb/client/model/Aggregates.html#setWindowFields(TExpression,org.bson.conversions.Bson,java.util.List>`__\ " >}}) + for the new `\ ``$setWindowFields`` `__ + pipeline stage of an aggregation pipeline. + +================= +What's new in 4.2 +================= + +This release fully supports all MongoDB releases from versions 2.6 to 4.4. New features of the 4.2 Java driver release include: + + +* The Reactive Streams driver now utilizes `Project Reactor `__ internally. Project reactor follows + the Reactive Streams specification and has greatly simplified the implementation of the driver. +* Added support for Azure and GCP key stores to client-side field level encryption. +* Added support for caching Kerberos tickets so that they can be re-used for multiple authentication requests. +* Added support for constructing legacy ``com.mongodb.MongoClient`` instances with ``MongoClientSettings`` or ``ConnectionString`` as + the configuration, instead of ``MongoClientOptions`` or ``MongoClientURI``. +* Added support for ``explain`` of ``find`` and ``aggregate`` commands. +* Added a ``JsonObject`` class to make encoding from and decoding to JSON more efficient by avoiding an intermediate ``Map`` representation. +* Added a ``BsonRepresentation`` annotation that allows ``ObjectId`` BSON values to be represented as ``String``\ s in POJO classes. +* Added support for the ``BsonIgnore`` annotation in Scala case classes. +* Added a ``Filters.empty()`` method. + +================= +What's new in 4.1 +================= + +This release fully supports all MongoDB releases from versions 2.6 to 4.4. Key new features of the 4.1 Java driver release include: + + +* Significant reduction in client-perceived failover times during planned maintenance events +* Update and delete operations support index hinting. +* The find operation supports allowDiskUse for sorts that require too much memory to execute in RAM. +* Authentication supports the MONGODB-AWS mechanism using Amazon Web Services (AWS) Identity and Access Management (IAM) credentials. +* Authentication requires fewer round trips to the server, resulting in faster connection setup. + +================= +What's new in 4.0 +================= + +This release adds no new features but, as a major release, contains breaking changes that may affect your application. Please consult the +`Upgrading Guide <{{}}>`__ for an enumeration of the breaking changes. + +================== +What's new in 3.12 +================== + +This release fully supports all MongoDB releases from versions 2.6 to 4.2. Key new features of the 3.12 Java driver release include: + +Security improvements +~~~~~~~~~~~~~~~~~~~~~ + +Client-side field level encryption is supported. Automatic encryption and decryption is available for users of +`MongoDB Enterprise Advanced `__\ , while explicit encryption and decryption is +available for users of MongoDB Community. + +See `Client-side Encryption <{{}}>`__ for further details. + +Improved interoperability when using the native UUID type +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The driver now supports setting the BSON binary representation of ``java.util.UUID`` instances via a new ``UuidRepresentation`` property on +``MongoClientSettings``. The default representation has not changed, but it will in the upcoming 4.0 major release of the driver. +Applications that store UUID values in MongoDB can use this setting to easily control the representation in MongoDB without having to +register a ``Codec`` in the ``CodecRegistry``. + +See `\ ``MongoClientSettings.getUuidRepresentation`` <{{< apiref "mongodb-driver-core" "com/mongodb/MongoClientSettings.html#getUuidRepresentation(>`__\ " >}}) for details. + +What's new in 3.11 +------------------ + +This release fully supports all MongoDB releases from versions 2.6 to 4.2. Key new features of the 3.11 Java driver release include: + +Improved transactions support +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +* The transactions API supports MongoDB 4.2 distributed transactions for use with sharded clusters. Distributed transactions use the same + API as replica set transactions. +* The sessions API supports the + `\ ``ClientSession.withTransaction()`` <{{< apiref "mongodb-driver-sync" "com/mongodb/client/ClientSession.html#withTransaction(com.mongodb.client.TransactionBody>`__ " >}}) + method to conveniently run a transaction with automatic retries and at-most-once semantics. +* The transactions API supports the + `\ ``maxCommitTime`` <{{< apiref "mongodb-driver-core" "com/mongodb/TransactionOptions.html#getMaxCommitTime(java.util.concurrent.TimeUnit>`__\ " >}}) option to control the + maximum amount of time to wait for a transaction to commit. + +Reliability improvements +~~~~~~~~~~~~~~~~~~~~~~~~ + + +* Most read operations are by default + `automatically retried `__. Supported read + operations that fail with a retryable error are retried automatically and transparently. +* `Retryable writes `__ are now enabled by default. Supported write + operations that fail with a retryable error are retried automatically and transparently, with at-most-once update semantics. +* DNS `SRV `__ records are periodically polled in order to update the mongos proxy list without + having to change client configuration or even restart the client application. This feature is particularly useful when used with a sharded + cluster on `MongoDB Atlas `__\ , which dynamically updates SRV records whenever you resize your Atlas + sharded cluster. +* Connections to the replica set primary are no longer closed after a step-down, allowing in progress read operations to complete. + +Security improvements +~~~~~~~~~~~~~~~~~~~~~ + +Client-side encryption is supported. Automatic encryption and decryption is available for users of +`MongoDB Enterprise Advanced `__\ , while explicit encryption and decryption is +available for users of MongoDB Community. + +See `Client-side Encryption <{{}}>`__ for further details. + +General improvements +~~~~~~~~~~~~~~~~~~~~ + + +* New `\ ``aggregate`` <{{< apiref "mongodb-driver-sync" "com/mongodb/client/MongoDatabase.html##aggregate(java.util.List>`__\ " >}}) helper methods support running + database-level aggregations. +* Aggregate helper methods now support the ``$merge`` pipeline stage, and + `\ ``Aggregates.merge()`` <{{< apiref "mongodb-driver-core" "com/mongodb/client/model/Aggregates.html#merge(java.lang.String>`__\ " >}}) builder methods support creation of + the new pipeline stage. +* `Zstandard `__ for wire protocol compression is supported in addition to Snappy and Zlib. +* Change stream helpers now support the ``startAfter`` option. +* Index creation helpers now support wildcard indexes. + +Full list of changes +~~~~~~~~~~~~~~~~~~~~ + + +* `New Features `__ +* `Improvements `__ +* `Bug Fixes `__ + +What's new in 3.10 +------------------ + +Key new features of the 3.10 Java driver release: + +Native asynchronous TLS/SSL support +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Previously, any use of our asynchronous drivers with TLS/SSl required the use of Netty. In 3.10, the driver supports asynchronous +TLS/SSL natively, so no third-party dependency is required. To accomplish this, the driver contains code vendored from +`https://github.com/marianobarrios/tls-channel `__. + +Operational improvements +~~~~~~~~~~~~~~~~~~~~~~~~ + +When connecting with the ``mongodb+srv`` protocol, the driver now polls DNS for changes to the SRV records when connected to a sharded +cluster. See +`Polling SRV Records for Mongos Discovery `__ +for more details. + +When retryable writes are enabled, the driver now outputs log messages at DEBUG level when a retryable write is attempted. See +`JAVA-2964 `__ for more details. + +Codec Improvements +~~~~~~~~~~~~~~~~~~ + +The driver now mutates the id property of a POJO, when inserting a document via a POJO with a ``null`` id property of type ``ObjectId``. See +`JAVA-2674 `__ for more details. + +JNDI +~~~~ + +The driver now offers a JNDI ``ObjectFactory`` implementation for creating instances of ``com.mongodb.client.MongoClient``\ , the interface +introduced in version 3.7 of the driver. See `JAVA-2883 `__ for more details. + +Full list of changes +~~~~~~~~~~~~~~~~~~~~ + + +* `New Features `__ +* `Improvements `__ +* `Bug Fixes `__ + +What's new in 3.9 +----------------- + +Key new features of the 3.9 Java driver release: + +Android support +~~~~~~~~~~~~~~~ + +The ``mongodb-driver-embedded-android`` module supports interaction with a MongoDB server running on an Android device. +See `MongoDB Mobile `__ for more details. + +Deprecations +~~~~~~~~~~~~ + +Numerous classes and methods have been deprecated in the 3.9 release in preparation for a major 4.0 release. See the +`Upgrading Guide <{{}}>`__ for more information. + +What's New in 3.8 +----------------- + +Key new features of the 3.8 Java driver release: + +Transactions +~~~~~~~~~~~~ + +The Java driver now provides support for executing CRUD operations within a transaction (requires MongoDB 4.0). See the +`Transactions and MongoDB Drivers `__ section +of the documentation and select the ``Java (Sync)`` tab. + +Change Stream enhancements +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Java driver now provides support for opening a change stream against an entire database, via new +`\ ``MongoDatabase.watch`` <{{< apiref "mongodb-driver-sync" "com/mongodb/client/MongoDatabase.html" >}}>`__ methods, or an +entire deployment, via new `\ ``MongoClient.watch`` <{{< apiref "mongodb-driver-sync" "com/mongodb/client/MongoClient.html" >}}>`__ methods. See +`Change Streams <{{}}>`__ for further details. + +SCRAM-256 Authentication Mechanism +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Java driver now provides support for the SCRAM-256 authentication mechanism (requires MongoDB 4.0). + +What's New in 3.7 +----------------- + +Key new features of the 3.7 Java driver release: + +Java 9 support +~~~~~~~~~~~~~~ + +Modules +``````` + +The Java driver now provides a set of JAR files that are compliant with the Java 9 +`module specification `__\ , and ``Automatic-Module-Name`` declarations have been added +to the manifests of those JAR files. See the `Installation Guide <{{}}>`__ +for information on which JAR files are now Java 9-compliant modules as well as what each of their module names is. + +Note that it was not possible to modularize all the existing JAR files due to the fact that, for some of them, packages are split amongst +multiple JAR files, and this violates a core rule of the Java 9 module system which states that at most one module contains classes for any +given package. For instance, the ``mongodb-driver`` and ``mongodb-driver-core`` JAR files both contain classes in the ``com.mongodb`` package, +and thus it's not possible to make both ``mongodb-driver`` and ``mongodb-driver-core`` Java 9 modules. Also so-called +"uber jars" like ``mongo-java-driver`` are not appropriate for Java 9 modularization, as they can conflict with their non-uber brethren, and +thus have not been given module names. + +Note that none of the modular JAR files contain ``module-info`` class files yet. Addition of these classes will be considered in a future +release. + +New Entry Point +``````````````` + +So that the driver can offer a modular option, a new entry point has been added to the ``com.mongodb.client`` package. +Static methods in this entry point, ``com.mongodb.client.MongoClients``\ , returns instances of a new ``com.mongodb.client.MongoClient`` +interface. This interface, while similar to the existing ``com.mongodb.MongoClient`` class in that it is a factory for +``com.mongodb.client.MongoDatabase`` instances, does not support the legacy ``com.mongodb.DBCollection``\ -based API, and thus does not suffer +from the aforementioned package-splitting issue that prevents Java 9 modularization. This new entry point is encapsulated in the new +``mongodb-driver-sync`` JAR file, which is also a Java 9-compliant module. + +The new entry point also moves the driver further in the direction of effective deprecation of the legacy API, which is now only available +only via the ``mongo-java-driver`` and ``mongodb-driver`` uber-jars, which are not Java 9 modules. At this point there are no plans to offer +the legacy API as a Java 9 module. + +See `Connect To MongoDB <{{}}>`__ for details on the new ``com.mongodb.client.MongoClients`` +and how it compares to the existing ``com.mongodb.MongoClient`` class. + +Unix domain socket support +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The 3.7 driver adds support for Unix domain sockets via the `\ ``jnr.unixsocket`` `__ library. +Connecting to Unix domain sockets is done via the `\ ``ConnectionString`` <{{< apiref "mongodb-driver-core" "com/mongodb/ConnectionString" >}}>`__ or via +`\ ``UnixServerAddress`` <{{< apiref "mongodb-driver-core" "com/mongodb/UnixServerAddress.html" >}}>`__. + +PojoCodec improvements +~~~~~~~~~~~~~~~~~~~~~~ + +The 3.7 release brings support for ``Map`` to the POJO ``Codec``. + +JSR-310 Instant, LocalDate & LocalDateTime support +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Support for ``Instant``\ , ``LocalDate`` and ``LocalDateTime`` has been added to the driver. The MongoDB Java drivers team would like to thank +`Cezary Bartosiak `__ for their excellent contribution to the driver. Users needing alternative data structures +and / or more flexibility regarding JSR-310 dates should check out the alternative JSR-310 codecs provider by Cezary: +`bson-codecs-jsr310 `__. + +JSR-305 NonNull annotations +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The public API is now annotated with JSR-305 compatible ``@NonNull`` and ``@Nullable`` annotations. This will allow programmers +to rely on tools like FindBugs/SpotBugs, IDEs like IntelliJ IDEA, and compilers like the Kotlin compiler to find errors in the use of the +driver via static analysis rather than via runtime failures. + +Improved logging of commands +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When the log level is set to DEBUG for the ``org.mongodb.driver.protocol.command`` logger, the driver now logs additional information to aid +in debugging: + + +* Before sending the command, it logs the full command (up to 1000 characters), and the request id. +* After receive a response to the command, it logs the request id and elapsed time in milliseconds. + +Here's an example + +.. code-block:: + + 10:37:29.099 [cluster-ClusterId {value='5a466138741fc252712a6d71', description='null'}-127.0.0.1:27017] DEBUG org.mongodb.driver.protocol.command - + Sending command '{ "hello" : 1, "$db" : "admin" } ...' with request id 4 to database admin on connection [connectionId{localValue:1, serverValue:1958}] to server 127.0.0.1:27017 + 10:37:29.104 [cluster-ClusterId{value='5a466138741fc252712a6d71', description='null'}-127.0.0.1:27017] DEBUG org.mongodb.driver.protocol.command - + Execution of command with request id 4 completed successfully in 22.44 ms on connection [connectionId {localValue:1, serverValue:1958}] to server 127.0.0.1:27017 + +Improved support for "raw" documents +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When working with "raw" BSON for improved performance via the `\ ``RawBsonDocument`` <{{< apiref "bson" "org/bson/RawBsonDocument" >}}>`__\ , the efficiency +of accessing embedded documents and arrays has been drastically improved by returning raw slices of the containing document or array. For +instance + +.. code-block:: java + + RawBsonDocument doc = new RawBsonDocument(bytes); + + // returns a RawBsonDocument that is a slice of the bytes from the containing doc + BsonDocument embeddedDoc = doc.getDocument("embeddedDoc"); + + // returns a RawBsonArray that is a slice of the bytes from the containing doc + BsonArray embeddedArray = doc.getArray("embeddedArray"); + + // returns a RawBsonDocument that is a slice of the bytes from the containing array + BsonDocument embeddedDoc2 = (BsonDocument) embeddedArray.get(0); + +What's New in 3.6 +----------------- + +Key new features of the 3.6 Java driver release: + +Change Stream support +~~~~~~~~~~~~~~~~~~~~~ + +The 3.6 release adds support for `change streams `__. + + +* `Change Stream Quick Start <{{}}>`__ +* `Change Stream Quick Start (Async) <{{}}>`__ + +Retryable writes +~~~~~~~~~~~~~~~~ + +The 3.6 release adds support for retryable writes using the ``retryWrites`` option in +`\ ``MongoClientOptions`` <{{< apiref "mongodb-driver-legacy" "com/mongodb/MongoClientOptions" >}}>`__. + +Compression +~~~~~~~~~~~ + +The 3.6 release adds support for compression of messages to and from appropriately configured MongoDB servers: + + +* `Compression Tutorial <{{}}>`__ +* `Compression Tutorial (Async) <{{}}>`__ + +Causal consistency +~~~~~~~~~~~~~~~~~~ + +The 3.6 release adds support for `causally consistency `__ via the new +`\ ``ClientSession`` <{{< apiref "mongodb-driver-core" "com/mongodb/session/ClientSession" >}}>`__ API. + +Application-configured server selection +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The 3.6 release adds support for application-configured control over server selection, using the ``serverSelector`` option in +`\ ``MongoClientOptions`` <{{< apiref "mongodb-driver-legacy" "com/mongodb/MongoClientOptions" >}}>`__. + +POJO Codec improvements +~~~~~~~~~~~~~~~~~~~~~~~ + +The 3.6 release brings new improvements to the POJO ``Codec``\ : + + +* Improved sub-class and discriminator support. +* Support for custom Collection and Map implementations. +* Improvements to the ``BsonCreator`` annotation, which now supports ``@BsonId`` and ``@BsonProperty`` with values that represent the read name of the property. +* A new `\ ``PropertyCodecProvider`` <{{< apiref "bson" "org/bson/codecs/pojo/PropertyCodecProvider" >}}>`__ API, allowing for easy and type-safe handling of container types. +* Added the `\ ``SET_PRIVATE_FIELDS_CONVENTION`` <{{< apiref "bson" "org/bson/codecs/pojo/Conventions.html#SET_PRIVATE_FIELDS_CONVENTION" >}}>`__ convention. +* Added the `\ ``USE_GETTERS_FOR_SETTERS`` <{{< apiref "bson" "org/bson/codecs/pojo/Conventions.html#USE_GETTERS_FOR_SETTERS" >}}>`__ convention. + +The MongoDB Java drivers team would like to thank both `Joseph Florencio `__ and `Qi Liu `__ +for their excellent contributions to the PojoCodec. + +What's New in 3.5 +----------------- + +Key new features of the 3.5 Java driver release: + +Native POJO support +~~~~~~~~~~~~~~~~~~~ + +The 3.5 release adds support for `POJO `__ serialization at the BSON layer, and can be +used by the synchronous and asynchronous drivers. See the POJO Quick start pages for details. + + +* `POJO Quick Start <{{}}>`__ +* `POJO Quick Start (Async) <{{}}>`__ +* `POJO Reference <{{}}>`__ + +Improved JSON support +~~~~~~~~~~~~~~~~~~~~~ + +The 3.5 release improves support for JSON parsing and generation. + + +* Implements the new `Extended JSON specification `__ +* Implements custom JSON converters to give applications full control over JSON generation for each BSON type + +See the `JSON reference <{{}}>`__ for details. + +Connection pool monitoring +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The 3.5 release adds support for monitoring connection pool-related events. + + +* `Connection pool monitoring in the driver <{{}}>`__ +* `Connection pool monitoring in the async driver <{{}}>`__ + +SSLContext configuration +~~~~~~~~~~~~~~~~~~~~~~~~ + +The 3.5 release supports overriding the default ``javax.net.ssl.SSLContext`` used for SSL connections to MongoDB. + + +* `SSL configuration in the driver <{{}}>`__ +* `SSL configuration in the async driver <{{}}>`__ + +KeepAlive configuration deprecated +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The 3.5 release deprecated socket keep-alive settings, also socket keep-alive checks are now on by default. +It is *strongly recommended* that system keep-alive settings should be configured with shorter timeouts. + +See the +`'does TCP keep-alive time affect MongoDB deployments?' <{{}}>`__ +documentation for more information. + +What's New in 3.4 +----------------- + +The 3.4 release includes full support for the MongoDB 3.4 server release. Key new features include: + +Support for Decimal128 Format +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: java + + import org.bson.types.Decimal128; + +The `Decimal128 <{{}}>`__ format supports numbers with up to 34 decimal digits +(i.e. significant digits) and an exponent range of −6143 to +6144. + +To create a ``Decimal128`` number, you can use + + +* + [\ ``Decimal128.parse()``\ ] ({{< apiref "bson" "org/bson/types/Decimal128.html" >}}) with a string: + + .. code-block:: + + ```java + Decimal128.parse("9.9900"); + ``` + +* + [\ ``new Decimal128()``\ ] ({{< apiref "bson" "org/bson/types/Decimal128.html" >}}) with a long: + +.. code-block:: + + ```java + new Decimal128(10L); + ``` + + + +* + [\ ``new Decimal128()``\ ] ({{< apiref "bson" "org/bson/types/Decimal128.html" >}}) with a ``java.math.BigDecimal``\ : + + .. code-block:: + + ```java + new Decimal128(new BigDecimal("4.350000")); + ``` + +Support for Collation +~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: java + + import com.mongodb.client.model.Collation; + +`Collation <{{}}>`__ allows users to specify language-specific rules for string +comparison. +Use the [\ ``Collation.builder()``\ ] ({{< apiref "mongodb-driver-core" "com/mongodb/client/model/Collation.html" >}}) +to create the ``Collation`` object. For example, the following example creates a ``Collation`` object with Primary level of comparison and `locale <{{}}>`__ ``fr``. + +.. code-block:: java + + Collation.builder().collationStrength(CollationStrength.PRIMARY).locale("fr").build())); + +You can specify collation at the collection level, at an index level, or at a collation-supported operation level: + +Collection Level +```````````````` + +To specify collation at the collection level, pass a ``Collation`` object as an option to the ``createCollection()`` method. To specify options to the ``createCollection`` method, use the `\ ``CreateCollectionOptions`` <{{< apiref "mongodb-driver-core" "com/mongodb/client/model/CreateCollectionOptions.html" >}}>`__ class. + +.. code-block:: java + + database.createCollection("myColl", new CreateCollectionOptions().collation( + Collation.builder() + .collationStrength(CollationStrength.PRIMARY) + .locale("fr").build())); + +Index Level +``````````` + +To specify collation for an index, pass a ``Collation`` object as an option to the ``createIndex()`` method. To specify index options, use the `IndexOptions <{{< apiref "mongodb-driver-core" "com/mongodb/client/model/IndexOptions.html" >}}>`__ class. + +.. code-block:: java + + IndexOptions collationIndexOptions = new IndexOptions().name("collation-fr") + .collation(Collation.builder() + .collationStrength(CollationStrength.SECONDARY) + .locale("fr").build()); + + collection.createIndex( + Indexes.ascending("name"), collationIndexOptions); + +Operation Level +``````````````` + +The following operations support collation by specifying the +``Collation`` object to their respective Iterable object. + + +* + ``MongoCollection.aggregate()`` + +* + ``MongoCollection.distinct()`` + +* + ``MongoCollection.find()`` + +* + ``MongoCollection.mapReduce()`` + +For example: + +.. code-block:: java + + Collation collation = Collation.builder() + .collationStrength(CollationStrength.SECONDARY) + .locale("fr").build(); + + collection.find(Filters.eq("category", "cafe")).collation(collation); + + collection.aggregate(Arrays.asList( + Aggregates.group("$category", Accumulators.sum("count", 1)))) + .collation(collation); + +The following operations support collation by specifying the +``Collation`` object as an option using the corresponding option class +for the method: + + +* ``MongoCollection.count()`` +* ``MongoCollection.deleteOne()`` +* ``MongoCollection.deleteMany()`` +* ``MongoCollection.findOneAndDelete()`` +* ``MongoCollection.findOneAndReplace()`` +* ``MongoCollection.findOneAndUpdate()`` +* ``MongoCollection.updateOne()`` +* ``MongoCollection.updateMany()`` +* + ``MongoCollection.bulkWrite()`` for: + + + * ``DeleteManyModel`` and ``DeleteOneModel`` using ``DeleteOptions`` to specify the collation + * ``ReplaceOneModel``\ , ``UpdateManyModel``\ , and ``UpdateOneModel`` using ``UpdateOptions`` to specify the collation. + +For example: + +.. code-block:: java + + Collation collation = Collation.builder() + .collationStrength(CollationStrength.SECONDARY) + .locale("fr").build(); + + collection.count(Filters.eq("category", "cafe"), new CountOptions().collation(collation)); + + collection.updateOne(Filters.eq("category", "cafe"), set("stars", 1), + new UpdateOptions().collation(collation)); + + collection.bulkWrite(Arrays.asList( + new UpdateOneModel<>(new Document("category", "cafe"), + new Document("$set", new Document("x", 0)), + new UpdateOptions().collation(collation)), + new DeleteOneModel<>(new Document("category", "cafe"), + new DeleteOptions().collation(collation)))); + +For more information on collation, including the supported locales, refer to the +`manual <{{}}>`__. + +Other MongoDB 3.4 features +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +* Support for specification of + `maximum staleness for secondary reads `__ +* Support for the + `MongoDB handshake protocol `__. +* Builders for `eight new aggregation pipeline stages <{{}}>`__ +* Helpers for creating `read-only views <{{}}>`__ +* Support for the `linearizable read concern `__ + +Support for JNDI +~~~~~~~~~~~~~~~~ + +The synchronous driver now includes a `JNDI <{{}}>`__ ObjectFactory implementation. + +Upgrading +--------- + +See the `upgrading guide <{{}}>`__ on how to upgrade to 3.5. diff --git a/source/test/laravel-eloquent-models.txt b/source/test/laravel-eloquent-models.txt new file mode 100644 index 000000000..ca5a60c08 --- /dev/null +++ b/source/test/laravel-eloquent-models.txt @@ -0,0 +1,480 @@ + +=============== +Eloquent Models +=============== + +Previous: `Installation and configuration `__ + +This package includes a MongoDB enabled Eloquent class that you can use to define models for corresponding collections. + +Extending the base model +~~~~~~~~~~~~~~~~~~~~~~~~ + +To get started, create a new model class in your ``app\Models\`` directory. + +.. code-block:: php + + namespace App\Models; + + use MongoDB\Laravel\Eloquent\Model; + + class Book extends Model + { + // + } + +Just like a normal model, the MongoDB model class will know which collection to use based on the model name. For ``Book``, the collection ``books`` will be used. + +To change the collection, pass the ``$collection`` property: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class Book extends Model + { + protected $collection = 'my_books_collection'; + } + +**NOTE:** MongoDB documents are automatically stored with a unique ID that is stored in the ``_id`` property. If you wish to use your own ID, substitute the ``$primaryKey`` property and set it to your own primary key attribute name. + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class Book extends Model + { + protected $primaryKey = 'id'; + } + + // MongoDB will also create _id, but the 'id' property will be used for primary key actions like find(). + Book::create(['id' => 1, 'title' => 'The Fault in Our Stars']); + +Likewise, you may define a ``connection`` property to override the name of the database connection that should be used when utilizing the model. + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class Book extends Model + { + protected $connection = 'mongodb'; + } + +Soft Deletes +~~~~~~~~~~~~ + +When soft deleting a model, it is not actually removed from your database. Instead, a ``deleted_at`` timestamp is set on the record. + +To enable soft delete for a model, apply the ``MongoDB\Laravel\Eloquent\SoftDeletes`` Trait to the model: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\SoftDeletes; + + class User extends Model + { + use SoftDeletes; + } + +For more information check `Laravel Docs about Soft Deleting `__. + +Prunable +~~~~~~~~ + +``Prunable`` and ``MassPrunable`` traits are Laravel features to automatically remove models from your database. You can use +``Illuminate\Database\Eloquent\Prunable`` trait to remove models one by one. If you want to remove models in bulk, you need +to use the ``MongoDB\Laravel\Eloquent\MassPrunable`` trait instead: it will be more performant but can break links with +other documents as it does not load the models. + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + use MongoDB\Laravel\Eloquent\MassPrunable; + + class Book extends Model + { + use MassPrunable; + } + +For more information check `Laravel Docs about Pruning Models `__. + +Dates +~~~~~ + +Eloquent allows you to work with Carbon or DateTime objects instead of MongoDate objects. Internally, these dates will be converted to MongoDate objects when saved to the database. + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class User extends Model + { + protected $casts = ['birthday' => 'datetime']; + } + +This allows you to execute queries like this: + +.. code-block:: php + + $users = User::where( + 'birthday', '>', + new DateTime('-18 years') + )->get(); + +Extending the Authenticatable base model +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This package includes a MongoDB Authenticatable Eloquent class ``MongoDB\Laravel\Auth\User`` that you can use to replace the default Authenticatable class ``Illuminate\Foundation\Auth\User`` for your ``User`` model. + +.. code-block:: php + + use MongoDB\Laravel\Auth\User as Authenticatable; + + class User extends Authenticatable + { + + } + +Guarding attributes +~~~~~~~~~~~~~~~~~~~ + +When choosing between guarding attributes or marking some as fillable, Taylor Otwell prefers the fillable route. +This is in light of `recent security issues described here `__. + +Keep in mind guarding still works, but you may experience unexpected behavior. + +Schema +------ + +The database driver also has (limited) schema builder support. You can easily manipulate collections and set indexes. + +Basic Usage +~~~~~~~~~~~ + +.. code-block:: php + + Schema::create('users', function ($collection) { + $collection->index('name'); + $collection->unique('email'); + }); + +You can also pass all the parameters specified `in the MongoDB docs `__ to the ``$options`` parameter: + +.. code-block:: php + + Schema::create('users', function ($collection) { + $collection->index( + 'username', + null, + null, + [ + 'sparse' => true, + 'unique' => true, + 'background' => true, + ] + ); + }); + +Inherited operations: + + +* create and drop +* collection +* hasCollection +* index and dropIndex (compound indexes supported as well) +* unique + +MongoDB specific operations: + + +* background +* sparse +* expire +* geospatial + +All other (unsupported) operations are implemented as dummy pass-through methods because MongoDB does not use a predefined schema. + +Read more about the schema builder on `Laravel Docs `__ + +Geospatial indexes +~~~~~~~~~~~~~~~~~~ + +Geospatial indexes are handy for querying location-based documents. + +They come in two forms: ``2d`` and ``2dsphere``. Use the schema builder to add these to a collection. + +.. code-block:: php + + Schema::create('bars', function ($collection) { + $collection->geospatial('location', '2d'); + }); + +To add a ``2dsphere`` index: + +.. code-block:: php + + Schema::create('bars', function ($collection) { + $collection->geospatial('location', '2dsphere'); + }); + +Relationships +------------- + +Basic Usage +~~~~~~~~~~~ + +The only available relationships are: + + +* hasOne +* hasMany +* belongsTo +* belongsToMany + +The MongoDB-specific relationships are: + + +* embedsOne +* embedsMany + +Here is a small example: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class User extends Model + { + public function items() + { + return $this->hasMany(Item::class); + } + } + +The inverse relation of ``hasMany`` is ``belongsTo``\ : + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class Item extends Model + { + public function user() + { + return $this->belongsTo(User::class); + } + } + +belongsToMany and pivots +~~~~~~~~~~~~~~~~~~~~~~~~ + +The belongsToMany relation will not use a pivot "table" but will push id's to a **related_ids** attribute instead. This makes the second parameter for the belongsToMany method useless. + +If you want to define custom keys for your relation, set it to ``null``\ : + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class User extends Model + { + public function groups() + { + return $this->belongsToMany( + Group::class, null, 'user_ids', 'group_ids' + ); + } + } + +EmbedsMany Relationship +~~~~~~~~~~~~~~~~~~~~~~~ + +If you want to embed models, rather than referencing them, you can use the ``embedsMany`` relation. This relation is similar to the ``hasMany`` relation but embeds the models inside the parent object. + +**REMEMBER**\ : These relations return Eloquent collections, they don't return query builder objects! + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class User extends Model + { + public function books() + { + return $this->embedsMany(Book::class); + } + } + +You can access the embedded models through the dynamic property: + +.. code-block:: php + + $user = User::first(); + + foreach ($user->books as $book) { + // + } + +The inverse relation is auto\ *magically* available. You don't need to define this reverse relation. + +.. code-block:: php + + $book = Book::first(); + + $user = $book->user; + +Inserting and updating embedded models works similar to the ``hasMany`` relation: + +.. code-block:: php + + $book = $user->books()->save( + new Book(['title' => 'A Game of Thrones']) + ); + + // or + $book = + $user->books() + ->create(['title' => 'A Game of Thrones']); + +You can update embedded models using their ``save`` method (available since release 2.0.0): + +.. code-block:: php + + $book = $user->books()->first(); + + $book->title = 'A Game of Thrones'; + $book->save(); + +You can remove an embedded model by using the ``destroy`` method on the relation, or the ``delete`` method on the model (available since release 2.0.0): + +.. code-block:: php + + $book->delete(); + + // Similar operation + $user->books()->destroy($book); + +If you want to add or remove an embedded model, without touching the database, you can use the ``associate`` and ``dissociate`` methods. + +To eventually write the changes to the database, save the parent object: + +.. code-block:: php + + $user->books()->associate($book); + $user->save(); + +Like other relations, embedsMany assumes the local key of the relationship based on the model name. You can override the default local key by passing a second argument to the embedsMany method: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class User extends Model + { + public function books() + { + return $this->embedsMany(Book::class, 'local_key'); + } + } + +Embedded relations will return a Collection of embedded items instead of a query builder. Check out the available operations here: https://laravel.com/docs/master/collections + +EmbedsOne Relationship +~~~~~~~~~~~~~~~~~~~~~~ + +The embedsOne relation is similar to the embedsMany relation, but only embeds a single model. + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class Book extends Model + { + public function author() + { + return $this->embedsOne(Author::class); + } + } + +You can access the embedded models through the dynamic property: + +.. code-block:: php + + $book = Book::first(); + $author = $book->author; + +Inserting and updating embedded models works similar to the ``hasOne`` relation: + +.. code-block:: php + + $author = $book->author()->save( + new Author(['name' => 'John Doe']) + ); + + // Similar + $author = + $book->author() + ->create(['name' => 'John Doe']); + +You can update the embedded model using the ``save`` method (available since release 2.0.0): + +.. code-block:: php + + $author = $book->author; + + $author->name = 'Jane Doe'; + $author->save(); + +You can replace the embedded model with a new model like this: + +.. code-block:: php + + $newAuthor = new Author(['name' => 'Jane Doe']); + + $book->author()->save($newAuthor); + +Cross-Database Relationships +---------------------------- + +If you're using a hybrid MongoDB and SQL setup, you can define relationships across them. + +The model will automatically return a MongoDB-related or SQL-related relation based on the type of the related model. + +If you want this functionality to work both ways, your SQL-models will need to use the ``MongoDB\Laravel\Eloquent\HybridRelations`` trait. + +**This functionality only works for ``hasOne``\ , ``hasMany`` and ``belongsTo``.** + +The SQL model should use the ``HybridRelations`` trait: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\HybridRelations; + + class User extends Model + { + use HybridRelations; + + protected $connection = 'mysql'; + + public function messages() + { + return $this->hasMany(Message::class); + } + } + +Within your MongoDB model, you should define the relationship: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class Message extends Model + { + protected $connection = 'mongodb'; + + public function user() + { + return $this->belongsTo(User::class); + } + } diff --git a/source/test/laravel-install.txt b/source/test/laravel-install.txt new file mode 100644 index 000000000..accf6377d --- /dev/null +++ b/source/test/laravel-install.txt @@ -0,0 +1,65 @@ +=============== +Getting Started +=============== + +Installation +------------ + +Make sure you have the MongoDB PHP driver installed. You can find installation instructions at https://php.net/manual/en/mongodb.installation.php + +Install the package via Composer: + +.. code-block:: bash + + $ composer require mongodb/laravel-mongodb + +In case your Laravel version does NOT autoload the packages, add the service provider to ``config/app.php``\ : + +.. code-block:: php + + 'providers' => [ + // ... + MongoDB\Laravel\MongoDBServiceProvider::class, + ], + +Configuration +------------- + +To configure a new MongoDB connection, add a new connection entry to ``config/database.php``\ : + +.. code-block:: php + + 'default' => env('DB_CONNECTION', 'mongodb'), + + 'connections' => [ + 'mongodb' => [ + 'driver' => 'mongodb', + 'dsn' => env('DB_DSN'), + 'database' => env('DB_DATABASE', 'homestead'), + ], + // ... + ], + +The ``dsn`` key contains the connection string used to connect to your MongoDB deployment. The format and available options are documented in the `MongoDB documentation `__. + +Instead of using a connection string, you can also use the ``host`` and ``port`` configuration options to have the connection string created for you. + +.. code-block:: php + + 'connections' => [ + 'mongodb' => [ + 'driver' => 'mongodb', + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', 27017), + 'database' => env('DB_DATABASE', 'homestead'), + 'username' => env('DB_USERNAME', 'homestead'), + 'password' => env('DB_PASSWORD', 'secret'), + 'options' => [ + 'appname' => 'homestead', + ], + ], + ], + +The ``options`` key in the connection configuration corresponds to the `uriOptions parameter `__. + +You are ready to `create your first MongoDB model `__. diff --git a/source/test/laravel-query-builder.txt b/source/test/laravel-query-builder.txt new file mode 100644 index 000000000..af954d210 --- /dev/null +++ b/source/test/laravel-query-builder.txt @@ -0,0 +1,537 @@ + +============= +Query Builder +============= + +The database driver plugs right into the original query builder. + +When using MongoDB connections, you will be able to build fluent queries to perform database operations. + +For your convenience, there is a ``collection`` alias for ``table`` as well as some additional MongoDB specific operators/operations. + +.. code-block:: php + + $books = DB::collection('books')->get(); + + $hungerGames = + DB::collection('books') + ->where('name', 'Hunger Games') + ->first(); + +If you are familiar with `Eloquent Queries `__\ , there is the same functionality. + +Available operations +-------------------- + +**Retrieving all models** + +.. code-block:: php + + $users = User::all(); + +**Retrieving a record by primary key** + +.. code-block:: php + + $user = User::find('517c43667db388101e00000f'); + +**Where** + +.. code-block:: php + + $posts = + Post::where('author.name', 'John') + ->take(10) + ->get(); + +**OR Statements** + +.. code-block:: php + + $posts = + Post::where('votes', '>', 0) + ->orWhere('is_approved', true) + ->get(); + +**AND statements** + +.. code-block:: php + + $users = + User::where('age', '>', 18) + ->where('name', '!=', 'John') + ->get(); + +**NOT statements** + +.. code-block:: php + + $users = User::whereNot('age', '>', 18)->get(); + +**whereIn** + +.. code-block:: php + + $users = User::whereIn('age', [16, 18, 20])->get(); + +When using ``whereNotIn`` objects will be returned if the field is non-existent. Combine with ``whereNotNull('age')`` to leave out those documents. + +**whereBetween** + +.. code-block:: php + + $posts = Post::whereBetween('votes', [1, 100])->get(); + +**whereNull** + +.. code-block:: php + + $users = User::whereNull('age')->get(); + +**whereDate** + +.. code-block:: php + + $users = User::whereDate('birthday', '2021-5-12')->get(); + +The usage is the same as ``whereMonth`` / ``whereDay`` / ``whereYear`` / ``whereTime`` + +**Advanced wheres** + +.. code-block:: php + + $users = + User::where('name', 'John') + ->orWhere(function ($query) { + return $query + ->where('votes', '>', 100) + ->where('title', '<>', 'Admin'); + })->get(); + +**orderBy** + +.. code-block:: php + + $users = User::orderBy('age', 'desc')->get(); + +**Offset & Limit (skip & take)** + +.. code-block:: php + + $users = + User::skip(10) + ->take(5) + ->get(); + +**groupBy** + +Selected columns that are not grouped will be aggregated with the ``$last`` function. + +.. code-block:: php + + $users = + Users::groupBy('title') + ->get(['title', 'name']); + +**Distinct** + +Distinct requires a field for which to return the distinct values. + +.. code-block:: php + + $users = User::distinct()->get(['name']); + + // Equivalent to: + $users = User::distinct('name')->get(); + +Distinct can be combined with **where**\ : + +.. code-block:: php + + $users = + User::where('active', true) + ->distinct('name') + ->get(); + +**Like** + +.. code-block:: php + + $spamComments = Comment::where('body', 'like', '%spam%')->get(); + +**Aggregation** + +**Aggregations are only available for MongoDB versions greater than 2.2.x** + +.. code-block:: php + + $total = Product::count(); + $price = Product::max('price'); + $price = Product::min('price'); + $price = Product::avg('price'); + $total = Product::sum('price'); + +Aggregations can be combined with **where**\ : + +.. code-block:: php + + $sold = Orders::where('sold', true)->sum('price'); + +Aggregations can be also used on sub-documents: + +.. code-block:: php + + $total = Order::max('suborder.price'); + +**NOTE**\ : This aggregation only works with single sub-documents (like ``EmbedsOne``\ ) not subdocument arrays (like ``EmbedsMany``\ ). + +**Incrementing/Decrementing the value of a column** + +Perform increments or decrements (default 1) on specified attributes: + +.. code-block:: php + + Cat::where('name', 'Kitty')->increment('age'); + + Car::where('name', 'Toyota')->decrement('weight', 50); + +The number of updated objects is returned: + +.. code-block:: php + + $count = User::increment('age'); + +You may also specify additional columns to update: + +.. code-block:: php + + Cat::where('age', 3) + ->increment('age', 1, ['group' => 'Kitty Club']); + + Car::where('weight', 300) + ->decrement('weight', 100, ['latest_change' => 'carbon fiber']); + +MongoDB-specific operators +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In addition to the Laravel Eloquent operators, all available MongoDB query operators can be used with ``where``\ : + +.. code-block:: php + + User::where($fieldName, $operator, $value)->get(); + +It generates the following MongoDB filter: + +.. code-block:: ts + + { $fieldName: { $operator: $value } } + +**Exists** + +Matches documents that have the specified field. + +.. code-block:: php + + User::where('age', 'exists', true)->get(); + +**All** + +Matches arrays that contain all elements specified in the query. + +.. code-block:: php + + User::where('roles', 'all', ['moderator', 'author'])->get(); + +**Size** + +Selects documents if the array field is a specified size. + +.. code-block:: php + + Post::where('tags', 'size', 3)->get(); + +**Regex** + +Selects documents where values match a specified regular expression. + +.. code-block:: php + + use MongoDB\BSON\Regex; + + User::where('name', 'regex', new Regex('.*doe', 'i'))->get(); + +**NOTE:** you can also use the Laravel regexp operations. These will automatically convert your regular expression string to a ``MongoDB\BSON\Regex`` object. + +.. code-block:: php + + User::where('name', 'regexp', '/.*doe/i')->get(); + +The inverse of regexp: + +.. code-block:: php + + User::where('name', 'not regexp', '/.*doe/i')->get(); + +**Type** + +Selects documents if a field is of the specified type. For more information check: http://docs.mongodb.org/manual/reference/operator/query/type/#op._S_type + +.. code-block:: php + + User::where('age', 'type', 2)->get(); + +**Mod** + +Performs a modulo operation on the value of a field and selects documents with a specified result. + +.. code-block:: php + + User::where('age', 'mod', [10, 0])->get(); + +MongoDB-specific Geo operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Near** + +.. code-block:: php + + $bars = Bar::where('location', 'near', [ + '$geometry' => [ + 'type' => 'Point', + 'coordinates' => [ + -0.1367563, // longitude + 51.5100913, // latitude + ], + ], + '$maxDistance' => 50, + ])->get(); + +**GeoWithin** + +.. code-block:: php + + $bars = Bar::where('location', 'geoWithin', [ + '$geometry' => [ + 'type' => 'Polygon', + 'coordinates' => [ + [ + [-0.1450383, 51.5069158], + [-0.1367563, 51.5100913], + [-0.1270247, 51.5013233], + [-0.1450383, 51.5069158], + ], + ], + ], + ])->get(); + +**GeoIntersects** + +.. code-block:: php + + $bars = Bar::where('location', 'geoIntersects', [ + '$geometry' => [ + 'type' => 'LineString', + 'coordinates' => [ + [-0.144044, 51.515215], + [-0.129545, 51.507864], + ], + ], + ])->get(); + +**GeoNear** + +You are able to make a ``geoNear`` query on mongoDB. +You don't need to specify the automatic fields on the model. +The returned instance is a collection. So you're able to make the `Collection `__ operations. +Just make sure that your model has a ``location`` field, and a `2ndSphereIndex `__. +The data in the ``location`` field must be saved as `GeoJSON `__. +The ``location`` points must be saved as `WGS84 `__ reference system for geometry calculation. That means, basically, you need to save ``longitude and latitude``\ , in that order specifically, and to find near with calculated distance, you ``need to do the same way``. + +.. code-block:: + + Bar::find("63a0cd574d08564f330ceae2")->update( + [ + 'location' => [ + 'type' => 'Point', + 'coordinates' => [ + -0.1367563, + 51.5100913 + ] + ] + ] + ); + $bars = Bar::raw(function ($collection) { + return $collection->aggregate([ + [ + '$geoNear' => [ + "near" => [ "type" => "Point", "coordinates" => [-0.132239, 51.511874] ], + "distanceField" => "dist.calculated", + "minDistance" => 0, + "maxDistance" => 6000, + "includeLocs" => "dist.location", + "spherical" => true, + ] + ] + ]); + }); + +Inserts, updates and deletes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Inserting, updating and deleting records works just like the original Eloquent. Please check `Laravel Docs' Eloquent section `__. + +Here, only the MongoDB-specific operations are specified. + +MongoDB specific operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Raw Expressions** + +These expressions will be injected directly into the query. + +.. code-block:: php + + User::whereRaw([ + 'age' => ['$gt' => 30, '$lt' => 40], + ])->get(); + + User::whereRaw([ + '$where' => '/.*123.*/.test(this.field)', + ])->get(); + + User::whereRaw([ + '$where' => '/.*123.*/.test(this["hyphenated-field"])', + ])->get(); + +You can also perform raw expressions on the internal MongoCollection object. If this is executed on the model class, it will return a collection of models. + +If this is executed on the query builder, it will return the original response. + +**Cursor timeout** + +To prevent ``MongoCursorTimeout`` exceptions, you can manually set a timeout value that will be applied to the cursor: + +.. code-block:: php + + DB::collection('users')->timeout(-1)->get(); + +**Upsert** + +Update or insert a document. Additional options for the update method are passed directly to the native update method. + +.. code-block:: php + + // Query Builder + DB::collection('users') + ->where('name', 'John') + ->update($data, ['upsert' => true]); + + // Eloquent + $user->update($data, ['upsert' => true]); + +**Projections** + +You can apply projections to your queries using the ``project`` method. + +.. code-block:: php + + DB::collection('items') + ->project(['tags' => ['$slice' => 1]]) + ->get(); + + DB::collection('items') + ->project(['tags' => ['$slice' => [3, 7]]]) + ->get(); + +**Projections with Pagination** + +.. code-block:: php + + $limit = 25; + $projections = ['id', 'name']; + + DB::collection('items') + ->paginate($limit, $projections); + +**Push** + +Add items to an array. + +.. code-block:: php + + DB::collection('users') + ->where('name', 'John') + ->push('items', 'boots'); + + $user->push('items', 'boots'); + +.. code-block:: php + + DB::collection('users') + ->where('name', 'John') + ->push('messages', [ + 'from' => 'Jane Doe', + 'message' => 'Hi John', + ]); + + $user->push('messages', [ + 'from' => 'Jane Doe', + 'message' => 'Hi John', + ]); + +If you **DON'T** want duplicate items, set the third parameter to ``true``\ : + +.. code-block:: php + + DB::collection('users') + ->where('name', 'John') + ->push('items', 'boots', true); + + $user->push('items', 'boots', true); + +**Pull** + +Remove an item from an array. + +.. code-block:: php + + DB::collection('users') + ->where('name', 'John') + ->pull('items', 'boots'); + + $user->pull('items', 'boots'); + +.. code-block:: php + + DB::collection('users') + ->where('name', 'John') + ->pull('messages', [ + 'from' => 'Jane Doe', + 'message' => 'Hi John', + ]); + + $user->pull('messages', [ + 'from' => 'Jane Doe', + 'message' => 'Hi John', + ]); + +**Unset** + +Remove one or more fields from a document. + +.. code-block:: php + + DB::collection('users') + ->where('name', 'John') + ->unset('note'); + + $user->unset('note'); + + $user->save(); + +Using the native ``unset`` on models will work as well: + +.. code-block:: php + + unset($user['note']); + unset($user->node); diff --git a/source/test/laravel.txt b/source/test/laravel.txt new file mode 100644 index 000000000..31e7876e6 --- /dev/null +++ b/source/test/laravel.txt @@ -0,0 +1,66 @@ +=============== +Laravel MongoDB +=============== + +.. meta:: + :keywords: php framework + +This package adds functionalities to the Eloquent model and Query builder for +MongoDB, using the original Laravel API. +*This library extends the original Laravel classes, so it uses exactly the +same methods.* + +This package was renamed to ``mongodb/laravel-mongodb`` because of a transfer +of ownership to MongoDB, Inc. It is compatible with Laravel 10.x. For older +versions of Laravel, please refer to the `old versions `__. + +- :ref:`laravel-install` +- :ref:`laravel-eloquent-models` +- :ref:`laravel-query-builder` +- :ref:`laravel-user-authentication` +- :ref:`laravel-transactions` +- :ref:`laravel-upgrading` +- :ref:`laravel-queues` + +Reporting Issues +---------------- + +Think you’ve found a bug in the library? Want to see a new feature? Please open a case in our issue management tool, JIRA: + +- `Create an account and login `__ +- Navigate to the `PHPORM `__ project. +- Click Create +- Please provide as much information as possible about the issue type and how to reproduce it. + +Note: All reported issues in JIRA project are public. + +For general questions and support requests, please use one of MongoDB's +:manual:`Technical Support `__ channels. + +Security Vulnerabilities +~~~~~~~~~~~~~~~~~~~~~~~~ + +If you've identified a security vulnerability in a driver or any other MongoDB +project, please report it according to the instructions in +`Create a Vulnerability Report `__. + + +Development +----------- + +Development is tracked in the `PHPORM `__ +project in MongoDB's JIRA. Documentation for contributing to this project may +be found in `CONTRIBUTING.md `__. + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + /install + /elequent-models + /query-builder + /user-authentication + /transactions + /upgrade + /queues + diff --git a/source/test/laravel/eloquent-models.txt b/source/test/laravel/eloquent-models.txt new file mode 100644 index 000000000..d415d8905 --- /dev/null +++ b/source/test/laravel/eloquent-models.txt @@ -0,0 +1,516 @@ +.. _laravel-eloquent-models: + +=============== +Eloquent Models +=============== + +Previous: :ref:`` + +This package includes a MongoDB enabled Eloquent class that you can use to +define models for corresponding collections. + +Extending the base model +~~~~~~~~~~~~~~~~~~~~~~~~ + +To get started, create a new model class in your ``app\Models\`` directory. + +.. code-block:: php + + namespace App\Models; + + use MongoDB\Laravel\Eloquent\Model; + + class Book extends Model + { + // + } + +Just like a normal model, the MongoDB model class will know which collection +to use based on the model name. For ``Book``\ , the collection ``books`` will +be used. + +To change the collection, pass the ``$collection`` property: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class Book extends Model + { + protected $collection = 'my_books_collection'; + } + +.. note:: + + MongoDB documents are automatically stored with a unique ID that is stored + in the ``_id`` property. If you wish to use your own ID, substitute the + ``$primaryKey`` property and set it to your own primary key attribute name. + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class Book extends Model + { + protected $primaryKey = 'id'; + } + + // MongoDB will also create _id, but the 'id' property will be used for primary key actions like find(). + Book::create(['id' => 1, 'title' => 'The Fault in Our Stars']); + +Likewise, you may define a ``connection`` property to override the name of the +database connection that should be used when utilizing the model. + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class Book extends Model + { + protected $connection = 'mongodb'; + } + +Soft Deletes +~~~~~~~~~~~~ + +When soft deleting a model, it is not actually removed from your database. +Instead, a ``deleted_at`` timestamp is set on the record. + +To enable soft delete for a model, apply the ``MongoDB\Laravel\Eloquent\SoftDeletes`` +Trait to the model: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\SoftDeletes; + + class User extends Model + { + use SoftDeletes; + } + +For more information check `Laravel Docs about Soft Deleting `__. + +Prunable +~~~~~~~~ + +``Prunable`` and ``MassPrunable`` traits are Laravel features to automatically +remove models from your database. You can use ``Illuminate\Database\Eloquent\Prunable`` +trait to remove models one by one. If you want to remove models in bulk, you +need to use the ``MongoDB\Laravel\Eloquent\MassPrunable`` trait instead: it +will be more performant but can break links with other documents as it does +not load the models. + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + use MongoDB\Laravel\Eloquent\MassPrunable; + + class Book extends Model + { + use MassPrunable; + } + +For more information check `Laravel Docs about Pruning Models `__. + +Dates +~~~~~ + +Eloquent allows you to work with Carbon or DateTime objects instead of MongoDate objects. Internally, these dates will be converted to MongoDate objects when saved to the database. + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class User extends Model + { + protected $casts = ['birthday' => 'datetime']; + } + +This allows you to execute queries like this: + +.. code-block:: php + + $users = User::where( + 'birthday', '>', + new DateTime('-18 years') + )->get(); + +Extending the Authenticatable base model +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This package includes a MongoDB Authenticatable Eloquent class ``MongoDB\Laravel\Auth\User`` +that you can use to replace the default Authenticatable class ``Illuminate\Foundation\Auth\User`` +for your ``User`` model. + +.. code-block:: php + + use MongoDB\Laravel\Auth\User as Authenticatable; + + class User extends Authenticatable + { + + } + +Guarding attributes +~~~~~~~~~~~~~~~~~~~ + +When choosing between guarding attributes or marking some as fillable, Taylor +Otwell prefers the fillable route. This is in light of +`recent security issues described here `__. + +Keep in mind guarding still works, but you may experience unexpected behavior. + +Schema +------ + +The database driver also has (limited) schema builder support. You can easily manipulate collections and set indexes. + +Basic Usage +~~~~~~~~~~~ + +.. code-block:: php + + Schema::create('users', function ($collection) { + $collection->index('name'); + $collection->unique('email'); + }); + +You can also pass all the parameters specified :manual:`in the MongoDB docs ` +to the ``$options`` parameter: + +.. code-block:: php + + Schema::create('users', function ($collection) { + $collection->index( + 'username', + null, + null, + [ + 'sparse' => true, + 'unique' => true, + 'background' => true, + ] + ); + }); + +Inherited operations: + + +* create and drop +* collection +* hasCollection +* index and dropIndex (compound indexes supported as well) +* unique + +MongoDB specific operations: + + +* background +* sparse +* expire +* geospatial + +All other (unsupported) operations are implemented as dummy pass-through +methods because MongoDB does not use a predefined schema. + +Read more about the schema builder on `Laravel Docs `__ + +Geospatial indexes +~~~~~~~~~~~~~~~~~~ + +Geospatial indexes are handy for querying location-based documents. + +They come in two forms: ``2d`` and ``2dsphere``. Use the schema builder to add +these to a collection. + +.. code-block:: php + + Schema::create('bars', function ($collection) { + $collection->geospatial('location', '2d'); + }); + +To add a ``2dsphere`` index: + +.. code-block:: php + + Schema::create('bars', function ($collection) { + $collection->geospatial('location', '2dsphere'); + }); + +Relationships +------------- + +Basic Usage +~~~~~~~~~~~ + +The only available relationships are: + + +* hasOne +* hasMany +* belongsTo +* belongsToMany + +The MongoDB-specific relationships are: + + +* embedsOne +* embedsMany + +Here is a small example: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class User extends Model + { + public function items() + { + return $this->hasMany(Item::class); + } + } + +The inverse relation of ``hasMany`` is ``belongsTo``: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class Item extends Model + { + public function user() + { + return $this->belongsTo(User::class); + } + } + +belongsToMany and pivots +~~~~~~~~~~~~~~~~~~~~~~~~ + +The belongsToMany relation will not use a pivot "table" but will push id's to +a **related_ids** attribute instead. This makes the second parameter for the +belongsToMany method useless. + +If you want to define custom keys for your relation, set it to ``null``: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class User extends Model + { + public function groups() + { + return $this->belongsToMany( + Group::class, null, 'user_ids', 'group_ids' + ); + } + } + +EmbedsMany Relationship +~~~~~~~~~~~~~~~~~~~~~~~ + +If you want to embed models, rather than referencing them, you can use the +``embedsMany`` relation. This relation is similar to the ``hasMany`` relation +but embeds the models inside the parent object. + +**REMEMBER**\ : These relations return Eloquent collections, they don't return +query builder objects! + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class User extends Model + { + public function books() + { + return $this->embedsMany(Book::class); + } + } + +You can access the embedded models through the dynamic property: + +.. code-block:: php + + $user = User::first(); + + foreach ($user->books as $book) { + // + } + +The inverse relation is auto\ *magically* available. You don't need to define +this reverse relation. + +.. code-block:: php + + $book = Book::first(); + + $user = $book->user; + +Inserting and updating embedded models works similar to the ``hasMany`` relation: + +.. code-block:: php + + $book = $user->books()->save( + new Book(['title' => 'A Game of Thrones']) + ); + + // or + $book = + $user->books() + ->create(['title' => 'A Game of Thrones']); + +You can update embedded models using their ``save`` method (available since +release 2.0.0): + +.. code-block:: php + + $book = $user->books()->first(); + + $book->title = 'A Game of Thrones'; + $book->save(); + +You can remove an embedded model by using the ``destroy`` method on the +relation, or the ``delete`` method on the model (available since release 2.0.0): + +.. code-block:: php + + $book->delete(); + + // Similar operation + $user->books()->destroy($book); + +If you want to add or remove an embedded model, without touching the database, +you can use the ``associate`` and ``dissociate`` methods. + +To eventually write the changes to the database, save the parent object: + +.. code-block:: php + + $user->books()->associate($book); + $user->save(); + +Like other relations, embedsMany assumes the local key of the relationship +based on the model name. You can override the default local key by passing a +second argument to the embedsMany method: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class User extends Model + { + public function books() + { + return $this->embedsMany(Book::class, 'local_key'); + } + } + +Embedded relations will return a Collection of embedded items instead of a +query builder. Check out the available operations here: +`https://laravel.com/docs/master/collections `__ + +EmbedsOne Relationship +~~~~~~~~~~~~~~~~~~~~~~ + +The embedsOne relation is similar to the embedsMany relation, but only embeds a single model. + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class Book extends Model + { + public function author() + { + return $this->embedsOne(Author::class); + } + } + +You can access the embedded models through the dynamic property: + +.. code-block:: php + + $book = Book::first(); + $author = $book->author; + +Inserting and updating embedded models works similar to the ``hasOne`` relation: + +.. code-block:: php + + $author = $book->author()->save( + new Author(['name' => 'John Doe']) + ); + + // Similar + $author = + $book->author() + ->create(['name' => 'John Doe']); + +You can update the embedded model using the ``save`` method (available since +release 2.0.0): + +.. code-block:: php + + $author = $book->author; + + $author->name = 'Jane Doe'; + $author->save(); + +You can replace the embedded model with a new model like this: + +.. code-block:: php + + $newAuthor = new Author(['name' => 'Jane Doe']); + + $book->author()->save($newAuthor); + +Cross-Database Relationships +---------------------------- + +If you're using a hybrid MongoDB and SQL setup, you can define relationships +across them. + +The model will automatically return a MongoDB-related or SQL-related relation +based on the type of the related model. + +If you want this functionality to work both ways, your SQL-models will need +to use the ``MongoDB\Laravel\Eloquent\HybridRelations`` trait. + +**This functionality only works for ``hasOne``\ , ``hasMany`` and ``belongsTo``.** + +The SQL model should use the ``HybridRelations`` trait: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\HybridRelations; + + class User extends Model + { + use HybridRelations; + + protected $connection = 'mysql'; + + public function messages() + { + return $this->hasMany(Message::class); + } + } + +Within your MongoDB model, you should define the relationship: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class Message extends Model + { + protected $connection = 'mongodb'; + + public function user() + { + return $this->belongsTo(User::class); + } + } diff --git a/source/test/laravel/install.txt b/source/test/laravel/install.txt new file mode 100644 index 000000000..939626522 --- /dev/null +++ b/source/test/laravel/install.txt @@ -0,0 +1,74 @@ +.. _laravel-install: + +=============== +Getting Started +=============== + +Installation +------------ + +Make sure you have the MongoDB PHP driver installed. You can find installation +instructions at `https://php.net/manual/en/mongodb.installation.php `__. + +Install the package via Composer: + +.. code-block:: bash + + $ composer require mongodb/laravel-mongodb + +In case your Laravel version does NOT autoload the packages, add the service +provider to ``config/app.php``: + +.. code-block:: php + + 'providers' => [ + // ... + MongoDB\Laravel\MongoDBServiceProvider::class, + ], + +Configuration +------------- + +To configure a new MongoDB connection, add a new connection entry to +``config/database.php``: + +.. code-block:: php + + 'default' => env('DB_CONNECTION', 'mongodb'), + + 'connections' => [ + 'mongodb' => [ + 'driver' => 'mongodb', + 'dsn' => env('DB_DSN'), + 'database' => env('DB_DATABASE', 'homestead'), + ], + // ... + ], + +The ``dsn`` key contains the connection string used to connect to your MongoDB +deployment. The format and available options are documented in the :manual:`MongoDB documentation . + +Instead of using a connection string, you can also use the ``host`` and +``port`` configuration options to have the connection string created for you. + +.. code-block:: php + + 'connections' => [ + 'mongodb' => [ + 'driver' => 'mongodb', + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', 27017), + 'database' => env('DB_DATABASE', 'homestead'), + 'username' => env('DB_USERNAME', 'homestead'), + 'password' => env('DB_PASSWORD', 'secret'), + 'options' => [ + 'appname' => 'homestead', + ], + ], + ], + +The ``options`` key in the connection configuration corresponds to the +`uriOptions `__ +parameter. + +You are ready to :ref:`create your first MongoDB model `. diff --git a/source/test/laravel/query-builder.txt b/source/test/laravel/query-builder.txt new file mode 100644 index 000000000..0f502fecf --- /dev/null +++ b/source/test/laravel/query-builder.txt @@ -0,0 +1,562 @@ +.. _laravel-query-builder: + +============= +Query Builder +============= + +The database driver plugs right into the original query builder. + +When using MongoDB connections, you will be able to build fluent queries to +perform database operations. + +For your convenience, there is a ``collection`` alias for ``table`` as well as +some additional MongoDB specific operators/operations. + +.. code-block:: php + + $books = DB::collection('books')->get(); + + $hungerGames = + DB::collection('books') + ->where('name', 'Hunger Games') + ->first(); + +If you are familiar with `Eloquent Queries `__, +there is the same functionality. + +Available operations +-------------------- + +**Retrieving all models** + +.. code-block:: php + + $users = User::all(); + +**Retrieving a record by primary key** + +.. code-block:: php + + $user = User::find('517c43667db388101e00000f'); + +**Where** + +.. code-block:: php + + $posts = + Post::where('author.name', 'John') + ->take(10) + ->get(); + +**OR Statements** + +.. code-block:: php + + $posts = + Post::where('votes', '>', 0) + ->orWhere('is_approved', true) + ->get(); + +**AND statements** + +.. code-block:: php + + $users = + User::where('age', '>', 18) + ->where('name', '!=', 'John') + ->get(); + +**NOT statements** + +.. code-block:: php + + $users = User::whereNot('age', '>', 18)->get(); + +**whereIn** + +.. code-block:: php + + $users = User::whereIn('age', [16, 18, 20])->get(); + +When using ``whereNotIn`` objects will be returned if the field is +non-existent. Combine with ``whereNotNull('age')`` to leave out those documents. + +**whereBetween** + +.. code-block:: php + + $posts = Post::whereBetween('votes', [1, 100])->get(); + +**whereNull** + +.. code-block:: php + + $users = User::whereNull('age')->get(); + +**whereDate** + +.. code-block:: php + + $users = User::whereDate('birthday', '2021-5-12')->get(); + +The usage is the same as ``whereMonth`` / ``whereDay`` / ``whereYear`` / ``whereTime`` + +**Advanced wheres** + +.. code-block:: php + + $users = + User::where('name', 'John') + ->orWhere(function ($query) { + return $query + ->where('votes', '>', 100) + ->where('title', '<>', 'Admin'); + })->get(); + +**orderBy** + +.. code-block:: php + + $users = User::orderBy('age', 'desc')->get(); + +**Offset & Limit (skip & take)** + +.. code-block:: php + + $users = + User::skip(10) + ->take(5) + ->get(); + +**groupBy** + +Selected columns that are not grouped will be aggregated with the ``$last`` +function. + +.. code-block:: php + + $users = + Users::groupBy('title') + ->get(['title', 'name']); + +**Distinct** + +Distinct requires a field for which to return the distinct values. + +.. code-block:: php + + $users = User::distinct()->get(['name']); + + // Equivalent to: + $users = User::distinct('name')->get(); + +Distinct can be combined with **where**\ : + +.. code-block:: php + + $users = + User::where('active', true) + ->distinct('name') + ->get(); + +**Like** + +.. code-block:: php + + $spamComments = Comment::where('body', 'like', '%spam%')->get(); + +**Aggregation** + +**Aggregations are only available for MongoDB versions greater than 2.2.x** + +.. code-block:: php + + $total = Product::count(); + $price = Product::max('price'); + $price = Product::min('price'); + $price = Product::avg('price'); + $total = Product::sum('price'); + +Aggregations can be combined with **where**\ : + +.. code-block:: php + + $sold = Orders::where('sold', true)->sum('price'); + +Aggregations can be also used on sub-documents: + +.. code-block:: php + + $total = Order::max('suborder.price'); + +.. note:: + + This aggregation only works with single sub-documents (like ``EmbedsOne``) + not subdocument arrays (like ``EmbedsMany``). + +**Incrementing/Decrementing the value of a column** + +Perform increments or decrements (default 1) on specified attributes: + +.. code-block:: php + + Cat::where('name', 'Kitty')->increment('age'); + + Car::where('name', 'Toyota')->decrement('weight', 50); + +The number of updated objects is returned: + +.. code-block:: php + + $count = User::increment('age'); + +You may also specify additional columns to update: + +.. code-block:: php + + Cat::where('age', 3) + ->increment('age', 1, ['group' => 'Kitty Club']); + + Car::where('weight', 300) + ->decrement('weight', 100, ['latest_change' => 'carbon fiber']); + +MongoDB-specific operators +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In addition to the Laravel Eloquent operators, all available MongoDB query +operators can be used with ``where``: + +.. code-block:: php + + User::where($fieldName, $operator, $value)->get(); + +It generates the following MongoDB filter: + +.. code-block:: ts + + { $fieldName: { $operator: $value } } + +**Exists** + +Matches documents that have the specified field. + +.. code-block:: php + + User::where('age', 'exists', true)->get(); + +**All** + +Matches arrays that contain all elements specified in the query. + +.. code-block:: php + + User::where('roles', 'all', ['moderator', 'author'])->get(); + +**Size** + +Selects documents if the array field is a specified size. + +.. code-block:: php + + Post::where('tags', 'size', 3)->get(); + +**Regex** + +Selects documents where values match a specified regular expression. + +.. code-block:: php + + use MongoDB\BSON\Regex; + + User::where('name', 'regex', new Regex('.*doe', 'i'))->get(); + +.. note:: + + You can also use the Laravel regexp operations. These will automatically + convert your regular expression string to a ``MongoDB\BSON\Regex`` object. + +.. code-block:: php + + User::where('name', 'regexp', '/.*doe/i')->get(); + +The inverse of regexp: + +.. code-block:: php + + User::where('name', 'not regexp', '/.*doe/i')->get(); + +**Type** + +Selects documents if a field is of the specified type. For more information +check: :manual:`$type ` in the +MongoDB Server documentation. + +.. code-block:: php + + User::where('age', 'type', 2)->get(); + +**Mod** + +Performs a modulo operation on the value of a field and selects documents with +a specified result. + +.. code-block:: php + + User::where('age', 'mod', [10, 0])->get(); + +MongoDB-specific Geo operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Near** + +.. code-block:: php + + $bars = Bar::where('location', 'near', [ + '$geometry' => [ + 'type' => 'Point', + 'coordinates' => [ + -0.1367563, // longitude + 51.5100913, // latitude + ], + ], + '$maxDistance' => 50, + ])->get(); + +**GeoWithin** + +.. code-block:: php + + $bars = Bar::where('location', 'geoWithin', [ + '$geometry' => [ + 'type' => 'Polygon', + 'coordinates' => [ + [ + [-0.1450383, 51.5069158], + [-0.1367563, 51.5100913], + [-0.1270247, 51.5013233], + [-0.1450383, 51.5069158], + ], + ], + ], + ])->get(); + +**GeoIntersects** + +.. code-block:: php + + $bars = Bar::where('location', 'geoIntersects', [ + '$geometry' => [ + 'type' => 'LineString', + 'coordinates' => [ + [-0.144044, 51.515215], + [-0.129545, 51.507864], + ], + ], + ])->get(); + +**GeoNear** + +You are able to make a ``geoNear`` query on mongoDB. +You don't need to specify the automatic fields on the model. +The returned instance is a collection. So you're able to make the +`Collection `__ operations. +Just make sure that your model has a ``location`` field, and a +`2ndSphereIndex `__. +The data in the ``location`` field must be saved as `GeoJSON `__. +The ``location`` points must be saved as `WGS84 `__ +reference system for geometry calculation. That means, basically, you need to +save ``longitude and latitude``, in that order specifically, and to find near +with calculated distance, you ``need to do the same way``. + +.. code-block:: + + Bar::find("63a0cd574d08564f330ceae2")->update( + [ + 'location' => [ + 'type' => 'Point', + 'coordinates' => [ + -0.1367563, + 51.5100913 + ] + ] + ] + ); + $bars = Bar::raw(function ($collection) { + return $collection->aggregate([ + [ + '$geoNear' => [ + "near" => [ "type" => "Point", "coordinates" => [-0.132239, 51.511874] ], + "distanceField" => "dist.calculated", + "minDistance" => 0, + "maxDistance" => 6000, + "includeLocs" => "dist.location", + "spherical" => true, + ] + ] + ]); + }); + +Inserts, updates and deletes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Inserting, updating and deleting records works just like the original Eloquent. +Please check `Laravel Docs' Eloquent section `__. + +Here, only the MongoDB-specific operations are specified. + +MongoDB specific operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Raw Expressions** + +These expressions will be injected directly into the query. + +.. code-block:: php + + User::whereRaw([ + 'age' => ['$gt' => 30, '$lt' => 40], + ])->get(); + + User::whereRaw([ + '$where' => '/.*123.*/.test(this.field)', + ])->get(); + + User::whereRaw([ + '$where' => '/.*123.*/.test(this["hyphenated-field"])', + ])->get(); + +You can also perform raw expressions on the internal MongoCollection object. +If this is executed on the model class, it will return a collection of models. + +If this is executed on the query builder, it will return the original response. + +**Cursor timeout** + +To prevent ``MongoCursorTimeout`` exceptions, you can manually set a timeout +value that will be applied to the cursor: + +.. code-block:: php + + DB::collection('users')->timeout(-1)->get(); + +**Upsert** + +Update or insert a document. Additional options for the update method are +passed directly to the native update method. + +.. code-block:: php + + // Query Builder + DB::collection('users') + ->where('name', 'John') + ->update($data, ['upsert' => true]); + + // Eloquent + $user->update($data, ['upsert' => true]); + +**Projections** + +You can apply projections to your queries using the ``project`` method. + +.. code-block:: php + + DB::collection('items') + ->project(['tags' => ['$slice' => 1]]) + ->get(); + + DB::collection('items') + ->project(['tags' => ['$slice' => [3, 7]]]) + ->get(); + +**Projections with Pagination** + +.. code-block:: php + + $limit = 25; + $projections = ['id', 'name']; + + DB::collection('items') + ->paginate($limit, $projections); + +**Push** + +Add items to an array. + +.. code-block:: php + + DB::collection('users') + ->where('name', 'John') + ->push('items', 'boots'); + + $user->push('items', 'boots'); + +.. code-block:: php + + DB::collection('users') + ->where('name', 'John') + ->push('messages', [ + 'from' => 'Jane Doe', + 'message' => 'Hi John', + ]); + + $user->push('messages', [ + 'from' => 'Jane Doe', + 'message' => 'Hi John', + ]); + +If you **DON'T** want duplicate items, set the third parameter to ``true``\ : + +.. code-block:: php + + DB::collection('users') + ->where('name', 'John') + ->push('items', 'boots', true); + + $user->push('items', 'boots', true); + +**Pull** + +Remove an item from an array. + +.. code-block:: php + + DB::collection('users') + ->where('name', 'John') + ->pull('items', 'boots'); + + $user->pull('items', 'boots'); + +.. code-block:: php + + DB::collection('users') + ->where('name', 'John') + ->pull('messages', [ + 'from' => 'Jane Doe', + 'message' => 'Hi John', + ]); + + $user->pull('messages', [ + 'from' => 'Jane Doe', + 'message' => 'Hi John', + ]); + +**Unset** + +Remove one or more fields from a document. + +.. code-block:: php + + DB::collection('users') + ->where('name', 'John') + ->unset('note'); + + $user->unset('note'); + + $user->save(); + +Using the native ``unset`` on models will work as well: + +.. code-block:: php + + unset($user['note']); + unset($user->node); diff --git a/source/test/laravel/queues.txt b/source/test/laravel/queues.txt new file mode 100644 index 000000000..828f489a4 --- /dev/null +++ b/source/test/laravel/queues.txt @@ -0,0 +1,39 @@ +.. _laravel-queues: + +====== +Queues +====== + +If you want to use MongoDB as your database backend for Laravel Queue, change +the driver in ``config/queue.php``: + +.. code-block:: php + + 'connections' => [ + 'database' => [ + 'driver' => 'mongodb', + // You can also specify your jobs specific database created on config/database.php + 'connection' => 'mongodb-job', + 'table' => 'jobs', + 'queue' => 'default', + 'expire' => 60, + ], + ], + +If you want to use MongoDB to handle failed jobs, change the database in +``config/queue.php``: + +.. code-block:: php + + 'failed' => [ + 'driver' => 'mongodb', + // You can also specify your jobs specific database created on config/database.php + 'database' => 'mongodb-job', + 'table' => 'failed_jobs', + ], + +Add the service provider in ``config/app.php``: + +.. code-block:: php + + MongoDB\Laravel\MongoDBQueueServiceProvider::class, diff --git a/source/test/laravel/transactions.txt b/source/test/laravel/transactions.txt new file mode 100644 index 000000000..05092ebdb --- /dev/null +++ b/source/test/laravel/transactions.txt @@ -0,0 +1,68 @@ +.. _laravel-transactions: + +============ +Transactions +============ + +Transactions require MongoDB version ^4.0 as well as deployment of replica set +or sharded clusters. You can find more information :manual:`in the MongoDB docs ` + +.. code-block:: php + + DB::transaction(function () { + User::create(['name' => 'john', 'age' => 19, 'title' => 'admin', 'email' => 'john@example.com']); + DB::collection('users')->where('name', 'john')->update(['age' => 20]); + DB::collection('users')->where('name', 'john')->delete(); + }); + +.. code-block:: php + + // begin a transaction + DB::beginTransaction(); + User::create(['name' => 'john', 'age' => 19, 'title' => 'admin', 'email' => 'john@example.com']); + DB::collection('users')->where('name', 'john')->update(['age' => 20]); + DB::collection('users')->where('name', 'john')->delete(); + + // commit changes + DB::commit(); + +To abort a transaction, call the ``rollBack`` method at any point during the transaction: + +.. code-block:: php + + DB::beginTransaction(); + User::create(['name' => 'john', 'age' => 19, 'title' => 'admin', 'email' => 'john@example.com']); + + // Abort the transaction, discarding any data created as part of it + DB::rollBack(); + + +.. note:: + + Transactions in MongoDB cannot be nested. DB::beginTransaction() function + will start new transactions in a new created or existing session and will + raise the RuntimeException when transactions already exist. See more in + MongoDB official docs :manual:`Transactions and Sessions `. + +.. code-block:: php + + DB::beginTransaction(); + User::create(['name' => 'john', 'age' => 20, 'title' => 'admin']); + + // This call to start a nested transaction will raise a RuntimeException + DB::beginTransaction(); + DB::collection('users')->where('name', 'john')->update(['age' => 20]); + DB::commit(); + DB::rollBack(); + +Database Testing +---------------- + +For testing, the traits ``Illuminate\Foundation\Testing\DatabaseTransactions`` +and ``Illuminate\Foundation\Testing\RefreshDatabase`` are not yet supported. +Instead, create migrations and use the ``DatabaseMigrations`` trait to reset +the database after each test: + +.. code-block:: php + + use Illuminate\Foundation\Testing\DatabaseMigrations; diff --git a/source/test/laravel/upgrade.txt b/source/test/laravel/upgrade.txt new file mode 100644 index 000000000..e7920fded --- /dev/null +++ b/source/test/laravel/upgrade.txt @@ -0,0 +1,42 @@ +.. _laravel-upgrading: + +========= +Upgrading +========= + +The PHP library uses `semantic versioning `__. Upgrading +to a new major version may require changes to your application. + +Upgrading from version 3 to 4 +----------------------------- + +- Laravel 10.x is required + +- Change dependency name in your composer.json to ``"mongodb/laravel-mongodb": "^4.0"`` + and run ``composer update`` + +- Change namespace from ``Jenssegers\Mongodb\`` to ``MongoDB\Laravel\`` + in your models and config + +- Remove support for non-Laravel projects + +- Replace ``$dates`` with ``$casts`` in your models + +- Call ``$model->save()`` after ``$model->unset('field')`` to persist the change + +- Replace calls to ``Query\Builder::whereAll($column, $values)`` with + ``Query\Builder::where($column, 'all', $values)`` + +- ``Query\Builder::delete()`` doesn't accept ``limit()`` other than ``1`` or ``null``. + +- ``whereDate``, ``whereDay``, ``whereMonth``, ``whereYear``, ``whereTime`` + now use MongoDB operators on date fields + +- Replace ``Illuminate\Database\Eloquent\MassPrunable`` with ``MongoDB\Laravel\Eloquent\MassPrunable`` + in your models + +- Remove calls to not-supported methods of ``Query\Builder``: ``toSql``, + ``toRawSql``, ``whereColumn``, ``whereFullText``, ``groupByRaw``, + ``orderByRaw``, ``unionAll``, ``union``, ``having``, ``havingRaw``, + ``havingBetween``, ``whereIntegerInRaw``, ``orWhereIntegerInRaw``, + ``whereIntegerNotInRaw``, ``orWhereIntegerNotInRaw``. diff --git a/source/test/laravel/user-authentication.txt b/source/test/laravel/user-authentication.txt new file mode 100644 index 000000000..6a7b69c99 --- /dev/null +++ b/source/test/laravel/user-authentication.txt @@ -0,0 +1,18 @@ +.. _laravel-user-authentication: + +=================== +User authentication +=================== + +If you want to use Laravel's native Auth functionality, register this included +service provider: + +.. code-block:: php + + MongoDB\Laravel\Auth\PasswordResetServiceProvider::class, + +This service provider will slightly modify the internal ``DatabaseReminderRepository`` +to add support for MongoDB based password reminders. + +If you don't use password reminders, you don't have to register this service +provider and everything else should work just fine.