willholley commented on code in PR #5432: URL: https://github.com/apache/couchdb/pull/5432#discussion_r1959552095
########## src/docs/src/ddocs/mango.rst: ########## @@ -0,0 +1,922 @@ +.. Licensed under the Apache License, Version 2.0 (the "License"); you may not +.. use this file except in compliance with the License. You may obtain a copy of +.. the License at +.. +.. http://www.apache.org/licenses/LICENSE-2.0 +.. +.. Unless required by applicable law or agreed to in writing, software +.. distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +.. WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +.. License for the specific language governing permissions and limitations under +.. the License. + +============= +Mango Queries +============= + +In addition to :ref:`map/reduce views <viewfun>`, CouchDB supports an expressive +query system called Mango. + +Mango consists of two major concepts: + +* Selectors, which are the queries, and are passed to the mango endpoints +* Indexes, which are a specialization of design docs used in mango queries + +There are a few important endpoints for interacting with these concepts: + +* :http:post:`/{db}/_find`, which executes a query +* :http:post:`/{db}/_explain`, which describes the execution of a query +* :http:get:`/{db}/_index` and :http:post:`/{db}/_index`, which manage indexes + +.. _find/selectors: + +Selectors +========= + +Selectors are expressed as a JSON object describing documents of interest. +Within this structure, you can apply conditional logic using specially named +fields. + +Whilst selectors have some similarities with MongoDB query documents, these +arise from a similarity of purpose and do not necessarily extend to commonality +of function or result. + +.. warning:: + + While CouchDB will happily store just about anything JSON, Mango has + limitations about what it can work with: + + * Empty field names (``""``) cannot be queried ("One or more conditions is + missing a field name.") + * Field names starting with ``$`` cannot be queried ("Invalid operator: $") + * Fields at the root of the document starting with ``_`` cannot be queried + ("Bad special document member: _") + +.. _find/selectorbasics: + +Selector Basics +--------------- + +Elementary selector syntax requires you to specify one or more fields, and the +corresponding values required for those fields. This selector matches all +documents whose ``"director"`` field has the value ``"Lars von Trier"``. + +.. code-block:: javascript + + { + "director": "Lars von Trier" + } + +A simple selector, inspecting specific fields: + +.. code-block:: javascript + + "selector": { + "title": "Live And Let Die" + }, + "fields": [ + "title", + "cast" + ] + +You can create more complex selector expressions by combining operators. +For best performance, it is best to combine 'combination' or +'array logical' operators, such as ``$regex``, with an operator +that defines a contiguous range of keys such as ``$eq``, +``$gt``, ``$gte``, ``$lt``, ``$lte``, and ``$beginsWith`` +(but not ``$ne``). For more information about creating complex +selector expressions, see :ref:`creating selector expressions +<find/expressions>`. + +.. _find/twofields: + +Selector with 2 fields +---------------------- + +This selector matches any document with a name field containing ``"Paul"``, +and that also has a location field with the value ``"Boston"``. + +.. code-block:: javascript + + { + "name": "Paul", + "location": "Boston" + } + +.. _find/subfields: + +Subfields +--------- + +A more complex selector enables you to specify the values for field of nested +objects, or subfields. For example, you might use a standard JSON structure for +specifying a field and subfield. + +Example of a field and subfield selector, using a standard JSON structure: + +.. code-block:: javascript + + { + "imdb": { + "rating": 8 + } + } + +An abbreviated equivalent uses a dot notation to combine the field and subfield +names into a single name. + +.. code-block:: javascript + + { + "imdb.rating": 8 + } + +.. _find/operators: + +Operators +--------- + +Operators are identified by the use of a dollar sign (``$``) prefix in the name +field. + +There are two core types of operators in the selector syntax: + +- Combination operators +- Condition operators + +In general, combination operators are applied at the topmost level of selection. +They are used to combine conditions, or to create combinations of conditions, +into one selector. + +Every explicit operator has the form: + +.. code-block:: javascript + + { + "$operator": argument + } + +A selector without an explicit operator is considered to have an implicit +operator. The exact implicit operator is determined by the structure of the +selector expression. + +.. _find/implicit_operators: + +Implicit Operators +------------------ + +There are two implicit operators: + +- Equality +- And + +In a selector, any field containing a JSON value, but that has no operators in +it, is considered to be an equality condition. The implicit equality test +applies also for fields and subfields. + +Any JSON object that is not the argument to a condition operator is an implicit +``$and`` operator on each field. + +In the below example, we use an operator to match any document, where the +``"year"`` field has a value greater than ``2010``: + +.. code-block:: javascript + + { + "year": { + "$gt": 2010 + } + } + +In this next example, there must be a field ``"director"`` in a matching +document, and the field must have a value exactly equal to ``"Lars von Trier"``. + +.. code-block:: javascript + + { + "director": "Lars von Trier" + } + +You can also make the equality operator explicit. + +.. code-block:: javascript + + { + "director": { + "$eq": "Lars von Trier" + } + } + +In the next example using subfields, the required field ``"imdb"`` in a matching +document must also have a subfield ``"rating"`` and the subfield must have a +value equal to ``8``. + +Example of implicit operator applied to a subfield test: + +.. code-block:: javascript + + { + "imdb": { + "rating": 8 + } + } + +Again, you can make the equality operator explicit. + +.. code-block:: javascript + + { + "imdb": { + "rating": { "$eq": 8 } + } + } + +An example of the ``$eq`` operator used with full text indexing: + +.. code-block:: javascript + + { + "selector": { + "year": { + "$eq": 2001 + } + }, + "sort": [ + "title:string" + ], + "fields": [ + "title" + ] + } + +An example of the ``$eq`` operator used with database indexed on the field ``"year"``: + +.. code-block:: javascript + + { + "selector": { + "year": { + "$eq": 2001 + } + }, + "sort": [ + "year" + ], + "fields": [ + "year" + ] + } + +In this example, the field ``"director"`` must be present and contain the value +``"Lars von Trier"`` and the field ``"year"`` must exist and have the value +``2003``. + +.. code-block:: javascript + + { + "director": "Lars von Trier", + "year": 2003 + } + +You can make both the ``$and`` operator and the equality operator explicit. + +Example of using explicit ``$and`` and ``$eq`` operators: + +.. code-block:: javascript + + { + "$and": [ + { + "director": { + "$eq": "Lars von Trier" + } + }, + { + "year": { + "$eq": 2003 + } + } + ] + } + +.. _find/explicit_operators: + +Explicit Operators +------------------ + +All operators, apart from 'Equality' and 'And', must be stated explicitly. + +.. _find/combination_operators: + +Combination Operators +--------------------- + +Combination operators are used to combine selectors. In addition to the common +boolean operators found in most programming languages, there are three +combination operators (``$all``, ``$elemMatch``, and ``$allMatch``) that help +you work with JSON arrays and one that works with JSON maps (``$keyMapMatch``). + +A combination operator takes a single argument. The argument is either another +selector, or an array of selectors. + +The list of combination operators: + ++------------------+----------+--------------------------------------------------+ +| Operator | Argument | Purpose | ++==================+==========+==================================================+ +| ``$and`` | Array | Matches if all the selectors in the array match. | ++------------------+----------+--------------------------------------------------+ +| ``$or`` | Array | Matches if any of the selectors in the array | +| | | match. All selectors must use the same index. | ++------------------+----------+--------------------------------------------------+ +| ``$not`` | Selector | Matches if the given selector does not match. | ++------------------+----------+--------------------------------------------------+ +| ``$nor`` | Array | Matches if none of the selectors in the array | +| | | match. | ++------------------+----------+--------------------------------------------------+ +| ``$all`` | Array | Matches an array value if it contains all the | +| | | elements of the argument array. | ++------------------+----------+--------------------------------------------------+ +| ``$elemMatch`` | Selector | Matches and returns all documents that contain an| +| | | array field with at least one element that | +| | | matches all the specified query criteria. | ++------------------+----------+--------------------------------------------------+ +| ``$allMatch`` | Selector | Matches and returns all documents that contain an| +| | | array field with all its elements matching all | +| | | the specified query criteria. | ++------------------+----------+--------------------------------------------------+ +| ``$keyMapMatch`` | Selector | Matches and returns all documents that contain a | +| | | map that contains at least one key that matches | +| | | all the specified query criteria. | ++------------------+----------+--------------------------------------------------+ +| ``$text`` | String | Perform a text search | ++------------------+----------+--------------------------------------------------+ + +.. _find/and: + +The ``$and`` operator +~~~~~~~~~~~~~~~~~~~~~ + +``$and`` operator used with two fields: + +.. code-block:: javascript + + { + "selector": { + "$and": [ + { + "title": "Total Recall" + }, + { + "year": { + "$in": [1984, 1991] + } + } + ] + }, + "fields": [ + "year", + "title", + "cast" + ] + } + +The ``$and`` operator matches if all the selectors in the array match. Below is +an example using the primary index (``_all_docs``): + +.. code-block:: javascript + + { + "$and": [ + { + "_id": { "$gt": null } + }, + { + "year": { + "$in": [2014, 2015] + } + } + ] + } + +.. _find/or: + +The ``$or`` operator +~~~~~~~~~~~~~~~~~~~~ + +The ``$or`` operator matches if any of the selectors in the array match. Below +is an example used with an index on the field ``"year"``: + +.. code-block:: javascript + + { + "year": 1977, + "$or": [ + { "director": "George Lucas" }, + { "director": "Steven Spielberg" } + ] + } + +.. _find/not: + +The ``$not`` operator +~~~~~~~~~~~~~~~~~~~~~ + +The ``$not`` operator matches if the given selector does not match. Below is an +example used with an index on the field ``"year"``: + +.. code-block:: javascript + + { + "year": { + "$gte": 1900, + "$lte": 1903 + }, + "$not": { + "year": 1901 + } + } + +.. _find/nor: + +The ``$nor`` operator +~~~~~~~~~~~~~~~~~~~~~ + +The ``$nor`` operator matches if the given selector does not match. Below is an +example used with an index on the field ``"year"``: + +.. code-block:: javascript + + { + "year": { + "$gte": 1900. + "$lte": 1910 + }, + "$nor": [ + { "year": 1901 }, + { "year": 1905 }, + { "year": 1907 } + ] + } + +.. _find/all: + +The ``$all`` operator +~~~~~~~~~~~~~~~~~~~~~ + +The ``$all`` operator matches an array value if it contains all the elements of +the argument array. Below is an example used with the primary index +(``_all_docs``): + +.. code-block:: javascript + + { + "_id": { + "$gt": null + }, + "genre": { + "$all": ["Comedy","Short"] + } + } + +.. _find/elemmatch: + +The ``$elemMatch`` operator +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``$elemMatch`` operator matches and returns all documents that contain an +array field with at least one element matching the supplied query criteria. +Below is an example used with the primary index (``_all_docs``): + +.. code-block:: javascript + + { + "_id": { "$gt": null }, + "genre": { + "$elemMatch": { + "$eq": "Horror" + } + } + } + +.. _find/allmatch: + +The ``$allMatch`` operator +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``$allMatch`` operator matches and returns all documents that contain an +array field with all its elements matching the supplied query criteria. Below +is an example used with the primary index (``_all_docs``): + +.. code-block:: javascript + + { + "_id": { "$gt": null }, + "genre": { + "$allMatch": { + "$eq": "Horror" + } + } + } + +.. _find/keymapmatch: + +The ``$keyMapMatch`` operator +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``$keyMapMatch`` operator matches and returns all documents that contain a +map that contains at least one key that matches all the specified query criteria. +Below is an example used with the primary index (``_all_docs``): + +.. code-block:: javascript + + { + "_id": { "$gt": null }, + "cameras": { + "$keyMapMatch": { + "$eq": "secondary" + } + } + } + +.. _find/text: + +The ``$text`` operator +~~~~~~~~~~~~~~~~~~~~~~ + +The ``$text`` operator performs a text search using either a search or nouveau +index. The specifics of the query follow either +:ref:`search syntax <ddoc/search/syntax>` or +:ref:`nouveau syntax <ddoc/nouveau/syntax>` (which both use Lucene and implement +the same syntax). + +.. code-block:: javascript + + { + "_id": { "$gt": null }, + "cameras": { + "$keyMapMatch": { + "$eq": "secondary" + } Review Comment: this code example looks copy/pasted from the previous one and should show a `$text` operator instead. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: notifications-unsubscr...@couchdb.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org