You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(db-mongodb): improve compatibility with Firestore database (#12763)
### What?
Adds four more arguments to the `mongooseAdapter`:
```typescript
useJoinAggregations?: boolean /* The big one */
useAlternativeDropDatabase?: boolean
useBigIntForNumberIDs?: boolean
usePipelineInSortLookup?: boolean
```
Also export a new `compatabilityOptions` object from
`@payloadcms/db-mongodb` where each key is a mongo-compatible database
and the value is the recommended `mongooseAdapter` settings for
compatability.
### Why?
When using firestore and visiting
`/admin/collections/media/payload-folders`, we get:
```
MongoServerError: invalid field(s) in lookup: [let, pipeline], only lookup(from, localField, foreignField, as) is supported
```
Firestore doesn't support the full MongoDB aggregation API used by
Payload which gets used when building aggregations for populating join
fields.
There are several other compatability issues with Firestore:
- The invalid `pipeline` property is used in the `$lookup` aggregation
in `buildSortParams`
- Firestore only supports number IDs of type `Long`, but Mongoose
converts custom ID fields of type number to `Double`
- Firestore does not support the `dropDatabase` command
- Firestore does not support the `createIndex` command (not addressed in
this PR)
### How?
```typescript
useJoinAggregations?: boolean /* The big one */
```
When this is `false` we skip the `buildJoinAggregation()` pipeline and resolve the join fields through multiple queries. This can potentially be used with AWS DocumentDB and Azure Cosmos DB to support join fields, but I have not tested with either of these databases.
```typescript
useAlternativeDropDatabase?: boolean
```
When `true`, monkey-patch (replace) the `dropDatabase` function so that
it calls `collection.deleteMany({})` on every collection instead of
sending a single `dropDatabase` command to the database
```typescript
useBigIntForNumberIDs?: boolean
```
When `true`, use `mongoose.Schema.Types.BigInt` for custom ID fields of type `number` which converts to a firestore `Long` behind the scenes
```typescript
usePipelineInSortLookup?: boolean
```
When `false`, modify the sortAggregation pipeline in `buildSortParams()` so that we don't use the `pipeline` property in the `$lookup` aggregation. Results in slightly worse performance when sorting by relationship properties.
### Limitations
This PR does not add support for transactions or creating indexes in firestore.
### Fixes
Fixed a bug (and added a test) where you weren't able to sort by multiple properties on a relationship field.
### Future work
1. Firestore supports simple `$lookup` aggregations but other databases might not. Could add a `useSortAggregations` property which can be used to disable aggregations in sorting.
---------
Co-authored-by: Claude <[email protected]>
Co-authored-by: Sasha <[email protected]>
|`autoPluralization`| Tell Mongoose to auto-pluralize any collection names if it encounters any singular words used as collection `slug`s. |
36
-
|`connectOptions`| Customize MongoDB connection options. Payload will connect to your MongoDB database using default options which you can override and extend to include all the [options](https://mongoosejs.com/docs/connections.html#options) available to mongoose. |
37
-
|`collectionsSchemaOptions`| Customize Mongoose schema options for collections. |
38
-
|`disableIndexHints`| Set to true to disable hinting to MongoDB to use 'id' as index. This is currently done when counting documents for pagination, as it increases the speed of the count function used in that query. Disabling this optimization might fix some problems with AWS DocumentDB. Defaults to false |
39
-
|`migrationDir`| Customize the directory that migrations are stored. |
40
-
|`transactionOptions`| An object with configuration properties used in [transactions](https://www.mongodb.com/docs/manual/core/transactions/) or `false` which will disable the use of transactions. |
41
-
|`collation`| Enable language-specific string comparison with customizable options. Available on MongoDB 3.4+. Defaults locale to "en". Example: `{ strength: 3 }`. For a full list of collation options and their definitions, see the [MongoDB documentation](https://www.mongodb.com/docs/manual/reference/collation/). |
42
-
|`allowAdditionalKeys`| By default, Payload strips all additional keys from MongoDB data that don't exist in the Payload schema. If you have some data that you want to include to the result but it doesn't exist in Payload, you can set this to `true`. Be careful as Payload access control _won't_ work for this data. |
43
-
|`allowIDOnCreate`| Set to `true` to use the `id` passed in data on the create API operations without using a custom ID field. |
44
-
|`disableFallbackSort`| Set to `true` to disable the adapter adding a fallback sort when sorting by non-unique fields, this can affect performance in some cases but it ensures a consistent order of results. |
|`autoPluralization`| Tell Mongoose to auto-pluralize any collection names if it encounters any singular words used as collection `slug`s. |
36
+
|`connectOptions`| Customize MongoDB connection options. Payload will connect to your MongoDB database using default options which you can override and extend to include all the [options](https://mongoosejs.com/docs/connections.html#options) available to mongoose. |
37
+
|`collectionsSchemaOptions`| Customize Mongoose schema options for collections. |
38
+
|`disableIndexHints`| Set to true to disable hinting to MongoDB to use 'id' as index. This is currently done when counting documents for pagination, as it increases the speed of the count function used in that query. Disabling this optimization might fix some problems with AWS DocumentDB. Defaults to false |
39
+
|`migrationDir`| Customize the directory that migrations are stored. |
40
+
|`transactionOptions`| An object with configuration properties used in [transactions](https://www.mongodb.com/docs/manual/core/transactions/) or `false` which will disable the use of transactions. |
41
+
|`collation`| Enable language-specific string comparison with customizable options. Available on MongoDB 3.4+. Defaults locale to "en". Example: `{ strength: 3 }`. For a full list of collation options and their definitions, see the [MongoDB documentation](https://www.mongodb.com/docs/manual/reference/collation/). |
42
+
|`allowAdditionalKeys`| By default, Payload strips all additional keys from MongoDB data that don't exist in the Payload schema. If you have some data that you want to include to the result but it doesn't exist in Payload, you can set this to `true`. Be careful as Payload access control _won't_ work for this data. |
43
+
|`allowIDOnCreate`| Set to `true` to use the `id` passed in data on the create API operations without using a custom ID field. |
44
+
|`disableFallbackSort`| Set to `true` to disable the adapter adding a fallback sort when sorting by non-unique fields, this can affect performance in some cases but it ensures a consistent order of results. |
45
+
|`useAlternativeDropDatabase`| Set to `true` to use an alternative `dropDatabase` implementation that calls `collection.deleteMany({})` on every collection instead of sending a raw `dropDatabase` command. Payload only uses `dropDatabase` for testing purposes. Defaults to `false`. |
46
+
|`useBigIntForNumberIDs`| Set to `true` to use `BigInt` for custom ID fields of type `'number'`. Useful for databases that don't support `double` or `int32` IDs. Defaults to `false`. |
47
+
|`useJoinAggregations`| Set to `false` to disable join aggregations (which use correlated subqueries) and instead populate join fields via multiple `find` queries. Defaults to `true`. |
48
+
|`usePipelineInSortLookup`| Set to `false` to disable the use of `pipeline` in the `$lookup` aggregation in sorting. Defaults to `true`. |
45
49
46
50
## Access to Mongoose models
47
51
@@ -56,9 +60,21 @@ You can access Mongoose models as follows:
56
60
57
61
## Using other MongoDB implementations
58
62
59
-
Limitations with [DocumentDB](https://aws.amazon.com/documentdb/) and [Azure Cosmos DB](https://azure.microsoft.com/en-us/products/cosmos-db):
63
+
You can import the `compatabilityOptions` object to get the recommended settings for other MongoDB implementations. Since these databases aren't officially supported by payload, you may still encounter issues even with these settings (please create an issue or PR if you believe these options should be updated):
60
64
61
-
- For Azure Cosmos DB you must pass `transactionOptions: false` to the adapter options. Azure Cosmos DB does not support transactions that update two and more documents in different collections, which is a common case when using Payload (via hooks).
62
-
- For Azure Cosmos DB the root config property `indexSortableFields` must be set to `true`.
63
-
- The [Join Field](../fields/join) is not supported in DocumentDB and Azure Cosmos DB, as we internally use MongoDB aggregations to query data for that field, which are limited there. This can be changed in the future.
64
-
- For DocumentDB pass `disableIndexHints: true` to disable hinting to the DB to use `id` as index which can cause problems with DocumentDB.
We export compatability options for [DocumentDB](https://aws.amazon.com/documentdb/), [Azure Cosmos DB](https://azure.microsoft.com/en-us/products/cosmos-db) and [Firestore](https://cloud.google.com/firestore/mongodb-compatibility/docs/overview). Known limitations:
78
+
79
+
- Azure Cosmos DB does not support transactions that update two or more documents in different collections, which is a common case when using Payload (via hooks).
80
+
- Azure Cosmos DB the root config property `indexSortableFields` must be set to `true`.
Copy file name to clipboardExpand all lines: packages/db-mongodb/src/index.ts
+41Lines changed: 41 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -143,6 +143,29 @@ export interface Args {
143
143
144
144
/** The URL to connect to MongoDB or false to start payload and prevent connecting */
145
145
url: false|string
146
+
147
+
/**
148
+
* Set to `true` to use an alternative `dropDatabase` implementation that calls `collection.deleteMany({})` on every collection instead of sending a raw `dropDatabase` command.
149
+
* Payload only uses `dropDatabase` for testing purposes.
150
+
* @default false
151
+
*/
152
+
useAlternativeDropDatabase?: boolean
153
+
/**
154
+
* Set to `true` to use `BigInt` for custom ID fields of type `'number'`.
155
+
* Useful for databases that don't support `double` or `int32` IDs.
156
+
* @default false
157
+
*/
158
+
useBigIntForNumberIDs?: boolean
159
+
/**
160
+
* Set to `false` to disable join aggregations (which use correlated subqueries) and instead populate join fields via multiple `find` queries.
161
+
* @default true
162
+
*/
163
+
useJoinAggregations?: boolean
164
+
/**
165
+
* Set to `false` to disable the use of `pipeline` in the `$lookup` aggregation in sorting.
166
+
* @default true
167
+
*/
168
+
usePipelineInSortLookup?: boolean
146
169
}
147
170
148
171
exporttypeMongooseAdapter={
@@ -159,6 +182,10 @@ export type MongooseAdapter = {
0 commit comments