Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOCSP-37057 eloquent schema builder #2776

Merged
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
decbd99
PHPORM-152 Fix tests for Carbon 3 (#2733)
GromNaN Feb 21, 2024
9b72148
PHPORM-150 Run CI on Laravel 11 (#2735)
GromNaN Feb 22, 2024
aee3510
Merge branch '4.1' into 4.2
GromNaN Feb 22, 2024
a05bd53
Merge branch '4.1' into 4.2
GromNaN Feb 26, 2024
ebaaf14
Merge branch '4.1' into 4.2
GromNaN Mar 5, 2024
34003dc
Merge branch '4.1' into 4.2
GromNaN Mar 6, 2024
e08f5ed
DOCSP-37057: Eloquent schema builder
Mar 6, 2024
cf0ea1a
Merge pull request #2754 from mongodb/merge-4.1-into-4.2-1709803162085
alcaeus Mar 7, 2024
963d01f
Test Laravel 10 and 11 (#2746)
GromNaN Mar 7, 2024
1004c39
wip
Mar 7, 2024
19fc801
PHPORM-139 Implement `Model::createOrFirst()` using `findOneAndUpdate…
GromNaN Mar 11, 2024
4d71a02
apply phpcbf formatting
ccho-mongodb Mar 12, 2024
7f10e27
wip
Mar 12, 2024
7d1c13e
apply phpcbf formatting
ccho-mongodb Mar 12, 2024
2c7c1a8
fix rst, organize sections
Mar 12, 2024
cc1b370
remove install toc entry
Mar 12, 2024
92efdda
Merge branch '4.2' into merge-4.1-into-4.2-1710254470287
alcaeus Mar 13, 2024
411735a
Merge pull request #2766 from mongodb/merge-4.1-into-4.2-1710254470287
alcaeus Mar 13, 2024
c8fb0a0
PHPORM-159 Add tests on `whereAny` and `whereAll` (#2763)
GromNaN Mar 13, 2024
f5f86c8
PHPORM-139 Improve `Model::createOrFirst()` tests and error checking …
GromNaN Mar 13, 2024
4aa33a0
wip
Mar 14, 2024
13a1127
Merge pull request #2773 from mongodb/merge-4.1-into-4.2-1710408389604
GromNaN Mar 14, 2024
f7e6f80
wip
Mar 14, 2024
265d29c
grammar and spelling corrections
Mar 14, 2024
fab7501
fix rst
Mar 14, 2024
9719367
tweaks
Mar 14, 2024
f4afab6
PHP code style updates
Mar 14, 2024
fcdad94
DOCSP-37710: v4.2 updates (#2774)
Mar 14, 2024
b55393c
Set distinct version for error (#2779)
GromNaN Mar 15, 2024
39c0fd0
PRR fixes
Mar 15, 2024
205961b
PRR fixes 2
Mar 15, 2024
7cec5b7
PRR fixes
Mar 18, 2024
7cdbf35
PRR fixes 2
Mar 18, 2024
26071ac
fix rst
Mar 18, 2024
e182c90
Update changelog for 4.2.0 (#2784)
GromNaN Mar 19, 2024
ac4504c
PRR fixes
Mar 19, 2024
9bf9b06
Merge branch 'mongodb:4.1' into 4.1
Mar 20, 2024
72221f5
Merge branch 'mongodb:4.2' into DOCSP-37057-eloquent-schema-builder
Mar 20, 2024
06dcdef
Revert "Merge branch 'mongodb:4.2' into DOCSP-37057-eloquent-schema-b…
Mar 20, 2024
3e599b5
Merge remote-tracking branch 'origin/4.1' into DOCSP-37057-eloquent-s…
Mar 20, 2024
2465ad3
PRR and branch fixes
Mar 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
518 changes: 12 additions & 506 deletions docs/eloquent-models.txt

Large diffs are not rendered by default.

390 changes: 390 additions & 0 deletions docs/eloquent-models/schema-builder.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,390 @@
.. _laravel-schema-builder:

==============
Schema Builder
==============

.. facet::
:name: genre
:values: tutorial

.. meta::
:keywords: php framework, odm, code example, schema facade, php artisan, eloquent, blueprint, artisan, migrate

.. contents:: On this page
:local:
:backlinks: none
:depth: 2
:class: singlecol

Overview
--------

Laravel provides a **facade** to access the schema builder class ``Schema``,
which lets you create and modify tables. Facades are static interfaces to
classes that make the syntax more concise and improve testability.

{+odm-short+} supports a subset of the index and collection management methods
in the Laravel ``Schema`` facade.

To learn more about facades, see `Facades <https://laravel.com/docs/{+laravel-docs-version+}/facades>`__
in the Laravel documentation.

The following sections describe the Laravel schema builder features available
in {+odm-short+} and show examples of how to use them:

- :ref:`<laravel-eloquent-migrations>`
- :ref:`<laravel-eloquent-collection-exists>`
- :ref:`<laravel-eloquent-indexes>`

.. note::

{+odm-short+} supports managing indexes and collections, but
excludes support for MongoDB JSON schemas for data validation. To learn
more about JSON schema validation, see :manual:`Schema Validation </core/schema-validation/>`
GromNaN marked this conversation as resolved.
Show resolved Hide resolved
in the {+server-docs-name+}.

.. _laravel-eloquent-migrations:

Perform Laravel Migrations
--------------------------

Laravel migrations let you programmatically create, modify, and delete
your database schema by running methods included in the ``Schema`` facade.
The following sections explain how to author a migration class when you use
a MongoDB database and how to run them.

Create a Migration Class
~~~~~~~~~~~~~~~~~~~~~~~~

You can create migration classes manually or generate them by using the
``php artisan make:migration`` command. If you generate them, you must make the
following changes to perform the schema changes on your MongoDB database:

- Replace the ``Illuminate\Database\Schema\Blueprint`` import with
``MongoDB\Laravel\Schema\Blueprint`` if it is referenced in your migration
- Specify ``mongodb`` in the ``$connection`` field
GromNaN marked this conversation as resolved.
Show resolved Hide resolved
- Use only commands and syntax supported by {+odm-short+}

.. tip::

Make sure you set ``DB_CONNECTION=mongodb`` in your ``.env`` configuration
file so that PHP artisan performs the migration on the correct database.

The following example migration class contains the following methods:

- ``up()``, which creates a collection and an index when you run the migration
- ``down()``, which drops the collection and all the indexes on it when you roll back the migration

.. literalinclude:: /includes/schema-builder/astronauts_migration.php
:dedent:
:language: php
:emphasize-lines: 6, 11

Run or Roll Back a Migration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To run the database migration from a class file, run the following PHP artisan
command after replacing the placeholder:

.. code-block:: bash

php artisan migrate --path=<path to your migration class file>

This artisan command runs the ``up()`` function in the class file to create
the collection and index in the database specified in the ``config/database.php``
file.

To roll back the migration, run the following PHP artisan command after
replacing the placeholder:

.. code-block:: bash

php artisan migrate:rollback --path=<path to your migration class file>

This command runs the ``down()`` function in the class file to drop the
collection and related indexes.

To learn more about Laravel migrations, see
`Database: Migrations <https://laravel.com/docs/{+laravel-docs-version+}/migrations>`__
in the Laravel documentation.

.. _laravel-eloquent-collection-exists:

Check Whether a Collection Exists
---------------------------------

To check whether a collection exists, call the ``hasCollection()`` method on
the ``Schema`` facade in your migration file. You can use this to
perform migration logic conditionally.

The following example migration creates a ``stars`` collection if a collection
named ``telescopes`` exists:

.. literalinclude:: /includes/schema-builder/stars_migration.php
:language: php
:dedent:
:start-after: begin conditional create
:end-before: end conditional create

.. _laravel-eloquent-indexes:

Manage Indexes
--------------

MongoDB indexes are data structures that improve query efficiency by reducing
the number of documents needed to retrieve query results. Certain indexes, such
as geospatial indexes, extend how you can query the data.

To improve query performance by using an index, make sure the index covers
the query. To learn more about indexes and query optimization, see the
jmikola marked this conversation as resolved.
Show resolved Hide resolved
following {+server-docs-name+} entries:

- :manual:`Indexes </indexes>`
- :manual:`Query Optimization </core/query-optimization/>`

The following sections show how you can use the schema builder to create and
drop various types of indexes on a collection.

Create an Index
~~~~~~~~~~~~~~~

To create indexes, call the ``create()`` method on the ``Schema`` facade
in your migration file. Pass it the collection name and a callback
method with a ``MongoDB\Laravel\Schema\Blueprint`` parameter. Specify the
index creation details on the ``Blueprint`` instance.

The following example migration creates indexes on the following collection
fields:

- Single field index on ``mission_type``
- Compound index on ``launch_location`` and ``launch_date``, specifying a descending sort order on ``launch_date``
- Unique index on the ``mission_id`` field, specifying the index name "unique_mission_id_idx"

Click the :guilabel:`VIEW OUTPUT` button to see the indexes created by running
the migration, including the default index on the ``_id`` field:

.. io-code-block::

.. input:: /includes/schema-builder/flights_migration.php
:language: php
:dedent:
:start-after: begin create index
:end-before: end create index

.. output::
:language: json
:visible: false

[
{ v: 2, key: { _id: 1 }, name: '_id_' },
{ v: 2, key: { mission_type: 1 }, name: 'mission_type_1' },
{
v: 2,
key: { launch_location: 1, launch_date: -1 },
name: 'launch_location_1_launch_date_-1'
},
{
v: 2,
key: { mission_id: 1 },
name: 'unique_mission_id_idx',
unique: true
}
]

Specify Index Options
~~~~~~~~~~~~~~~~~~~~~

MongoDB index options determine how the indexes are used and stored.
You can specify index options when calling an index creation method, such
as ``index()``, on a ``Blueprint`` instance.

The following migration code shows how to add a collation to an index as an
index option. Click the :guilabel:`VIEW OUTPUT` button to see the indexes
jordan-smith721 marked this conversation as resolved.
Show resolved Hide resolved
created by running the migration, including the default index on the ``_id``
field:

.. io-code-block::

.. input:: /includes/schema-builder/passengers_migration.php
:language: php
:dedent:
:start-after: begin index options
:end-before: end index options

.. output::
:language: json
:visible: false

[
{ v: 2, key: { _id: 1 }, name: '_id_' },
{
v: 2,
key: { last_name: 1 },
name: 'passengers_collation_idx',
collation: {
locale: 'de@collation=phonebook',
caseLevel: false,
caseFirst: 'off',
strength: 3,
numericOrdering: true,
alternate: 'non-ignorable',
maxVariable: 'punct',
normalization: false,
backwards: false,
version: '57.1'
}
}
]

To learn more about index options, see :manual:`Options for All Index Types </reference/method/db.collection.createIndex/#options-for-all-index-types>`
in the {+server-docs-name+}.

Create Sparse, TTL, and Unique Indexes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

You can use {+odm-short+} helper methods to create the following types of
indexes:

- Sparse indexes, which allow index entries only for documents that contain the
specified field
- Time-to-live (TTL) indexes, which expire after a set amount of time
- Unique indexes, which prevent inserting documents that contain duplicate
values for the indexed field

To create these index types, call the ``create()`` method on the ``Schema`` facade
in your migration file. Pass ``create()`` the collection name and a callback
method with a ``MongoDB\Laravel\Schema\Blueprint`` parameter. Call the
appropriate helper method on the ``Blueprint`` instance and pass the
index creation details.

The following migration code shows how to create a sparse and a TTL index
by using the index helpers. Click the :guilabel:`VIEW OUTPUT` button to see
the indexes created by running the migration, including the default index on
jordan-smith721 marked this conversation as resolved.
Show resolved Hide resolved
the ``_id`` field:

.. io-code-block::

.. input:: /includes/schema-builder/planets_migration.php
:language: php
:dedent:
:start-after: begin index helpers
:end-before: end index helpers

.. output::
:language: json
:visible: false

[
{ v: 2, key: { _id: 1 }, name: '_id_' },
{ v: 2, key: { rings: 1 }, name: 'rings_1', sparse: true },
{
v: 2,
key: { last_visible_dt: 1 },
name: 'last_visible_dt_1',
expireAfterSeconds: 86400
}
]

You can specify sparse, TTL, and unique indexes on either a single field or
compound index by specifying them in the index options.

The following migration code shows how to create all three types of indexes
on a single field. Click the :guilabel:`VIEW OUTPUT` button to see the indexes
created by running the migration, including the default index on the ``_id``
jordan-smith721 marked this conversation as resolved.
Show resolved Hide resolved
field:

.. io-code-block::

.. input:: /includes/schema-builder/planets_migration.php
:language: php
:dedent:
:start-after: begin multi index helpers
:end-before: end multi index helpers

.. output::
:language: json
:visible: false

[
{ v: 2, key: { _id: 1 }, name: '_id_' },
{
v: 2,
key: { last_visible_dt: 1 },
name: 'last_visible_dt_1',
unique: true,
sparse: true,
expireAfterSeconds: 3600
}
]

To learn more about these indexes, see :manual:`Index Properties </core/indexes/index-properties/>`
in the {+server-docs-name+}.

Create a Geospatial Index
~~~~~~~~~~~~~~~~~~~~~~~~~

In MongoDB, geospatial indexes let you query geospatial coordinate data for
inclusion, intersection, and proximity.

To create geospatial indexes, call the ``create()`` method on the ``Schema`` facade
in your migration file. Pass ``create()`` the collection name and a callback
method with a ``MongoDB\Laravel\Schema\Blueprint`` parameter. Specify the
geospatial index creation details on the ``Blueprint`` instance.

The following example migration creates a ``2d`` and ``2dsphere`` geospatial
index on the ``spaceports`` collection. Click the :guilabel:`VIEW OUTPUT`
button to see the indexes created by running the migration, including the
jordan-smith721 marked this conversation as resolved.
Show resolved Hide resolved
default index on the ``_id`` field:

.. io-code-block::
.. input:: /includes/schema-builder/spaceports_migration.php
:language: php
:dedent:
:start-after: begin create geospatial index
:end-before: end create geospatial index

.. output::
:language: json
:visible: false

[
{ v: 2, key: { _id: 1 }, name: '_id_' },
{
v: 2,
key: { launchpad_location: '2dsphere' },
name: 'launchpad_location_2dsphere',
'2dsphereIndexVersion': 3
},
{ v: 2, key: { runway_location: '2d' }, name: 'runway_location_2d' }
]


To learn more about geospatial indexes, see
:manual:`Geospatial Indexes </core/indexes/index-types/index-geospatial/>` in
the {+server-docs-name+}.

Drop an Index
~~~~~~~~~~~~~

To drop indexes from a collection, call the ``table()`` method on the
``Schema`` facade in your migration file. Pass it the table name and a
callback method with a ``MongoDB\Laravel\Schema\Blueprint`` parameter.
Call the ``dropIndex()`` method with the index name on the ``Blueprint``
instance.

.. note::

If you drop a collection, MongoDB automatically drops all the indexes
associated with it.

The following example migration drops an index called ``unique_mission_id_idx``
from the ``flights`` collection:

.. literalinclude:: /includes/schema-builder/flights_migration.php
:language: php
:dedent:
:start-after: begin drop index
:end-before: end drop index


GromNaN marked this conversation as resolved.
Show resolved Hide resolved
Loading
Loading