v2.1 #10
@ -12,7 +12,8 @@ There are several categories of operations that can be accomplished against docu
|
||||
- **Save** adds a new document, updating an existing one if the ID is already present ("upsert")
|
||||
- **Update** updates an existing document, doing nothing if no documents satisfy the criteria
|
||||
- **Patch** updates a portion of an existing document, doing nothing if no documents satisfy the criteria
|
||||
- **Find** returns the documents matching some criteria
|
||||
- **Find** returns the documents matching some criteria as domain objects
|
||||
- **Json** returns documents as JSON strings or outputs that JSON directly
|
||||
- **RemoveFields** removes fields from documents matching some criteria
|
||||
- **Delete** removes documents matching some criteria
|
||||
|
||||
@ -23,7 +24,7 @@ There are several categories of operations that can be accomplished against docu
|
||||
- **byContains** (PostgreSQL only) uses a JSON containment query (the `@>` operator) to find documents where the given sub-document occurs (think of this as an `=` comparison based on one or more properties in the document; looking for hotels with `{ "country": "USA", "rating": 4 }` would find all hotels with a rating of 4 in the United States); applies to all but Update
|
||||
- **byJsonPath** (PostgreSQL only) uses a JSON patch match query (the `@?` operator) to make specific queries against a document's structure (it also supports more operators than a containment query; to find all hotels rated 4 _or higher_ in the United States, we could query for `"$ ? (@.country == \"USA\" && @.rating > 4)"`); applies to all but Update
|
||||
|
||||
Finally, `Find` also has `firstBy*` implementations for all supported criteria types.
|
||||
Finally, `Find` and `Json` also has `firstBy*` implementations for all supported criteria types.
|
||||
|
||||
## Saving Documents
|
||||
|
||||
@ -62,10 +63,15 @@ For SQLite, we can utilize a `Field` query with a between operator. (This will a
|
||||
|
||||
```php
|
||||
// SQLite
|
||||
Patch::byFields('room', [Field::between('roomNumber', 221, 240)], ['inService' => false]);
|
||||
Patch::byFields('room',
|
||||
[Field::equal('hotelId', 'abc'), Field::between('roomNumber', 221, 240)],
|
||||
['inService' => false]);
|
||||
```
|
||||
|
||||
## Finding Documents
|
||||
> [!NOTE]
|
||||
> When multiple fields are provided to any `*byFields` function, the default matching behavior is `FieldMatch.All`; any documents identified will match all criteria. Passing `FieldMatch.Any` modifies this behavior to identify documents where any one of the criteria match.
|
||||
|
||||
## Finding Documents as Domain Items
|
||||
|
||||
Functions to find documents start with `Find::`. There are variants to find all documents in a table, find by ID, find by JSON field comparison, find by JSON containment, or find by JSON Path. The hotel update example above utilizes an ID lookup; the descriptions of JSON containment and JSON Path show examples of the criteria used to retrieve using those techniques.
|
||||
|
||||
@ -109,6 +115,13 @@ foreach ($result->items as $item) {
|
||||
// Do something amazing with $item
|
||||
}
|
||||
```
|
||||
## Finding Documents as JSON
|
||||
|
||||
If an application serves endpoints that return JSON, taking the time to retrieve documents, deserialize them into objects, then turning around and serializing those same documents back to JSON - there's a lot of unnecessary processing going on. Static functions on the `Json` object address this by returning, or directly outputting, the JSON text received from the database.
|
||||
|
||||
`Json` has the same function names as `Find`, and these functions return the JSON as a string. These always return some string with valid JSON; an empty multiple-document request will be `[]`, and a one-or-none document request will be `{}` in the "none" scenario.
|
||||
|
||||
A second set of functions are prefixed with `output` (ex. `Json::outputAll`); these functions `echo` the JSON as it is retrieved from the database. This is the preferred method for JSON APIs, as it incurs no intermediate overhead; take the documents from the database and ship 'em off to the distant end. As these responses end up as a stream of text, we will need to identify this as JSON; `Json::setContentType()` will do this, and should be called before any other output is sent.
|
||||
|
||||
## Deleting Documents
|
||||
|
||||
@ -126,14 +139,14 @@ Functions to check for existence start with `Exists::`. Documents may be checked
|
||||
|
||||
The table below shows which commands are available for each access method. (X = supported for both, P = PostgreSQL only)
|
||||
|
||||
| Operation | `all` | `byId` | `byFields` | `byContains` | `byJsonPath` | `firstByFields` | `firstByContains` | `firstByJsonPath` |
|
||||
|----------------|:-----:|:------:|:----------:|:------------:|:------------:|:---------------:|:-----------------:|:-----------------:|
|
||||
| `Count` | X | | X | P | P | | | |
|
||||
| `Exists` | | X | X | P | P | | | |
|
||||
| `Find` | X | X | X | P | P | X | P | P |
|
||||
| `Patch` | | X | X | P | P | | | |
|
||||
| `RemoveFields` | | X | X | P | P | | | |
|
||||
| `Delete` | | X | X | P | P | | | |
|
||||
| Operation | `all` | `byId` | `byFields` | `byContains` | `byJsonPath` | `firstByFields` | `firstByContains` | `firstByJsonPath` |
|
||||
|-----------------|:-----:|:------:|:----------:|:------------:|:------------:|:---------------:|:-----------------:|:-----------------:|
|
||||
| `Count` | X | | X | P | P | | | |
|
||||
| `Exists` | | X | X | P | P | | | |
|
||||
| `Find` / `Json` | X | X | X | P | P | X | P | P |
|
||||
| `Patch` | | X | X | P | P | | | |
|
||||
| `RemoveFields` | | X | X | P | P | | | |
|
||||
| `Delete` | | X | X | P | P | | | |
|
||||
|
||||
`Document::insert`, `Document::save`, and `Document::update` operate on single documents.
|
||||
|
||||
|
@ -241,4 +241,12 @@ class Json
|
||||
{
|
||||
echo self::firstByJsonPath($tableName, $path, $orderBy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the content type of this page's output to JSON
|
||||
*/
|
||||
public static function setContentType(): void
|
||||
{
|
||||
header('Content-Type: application/json');
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user