{"id":19903399,"url":"https://github.com/stargate/stargate-mongoose","last_synced_at":"2025-05-03T00:31:00.029Z","repository":{"id":65961028,"uuid":"579179592","full_name":"stargate/stargate-mongoose","owner":"stargate","description":"Mongoose Node.js package for Apache Cassandra / DataStax Astra","archived":false,"fork":false,"pushed_at":"2025-04-30T20:30:48.000Z","size":1412,"stargazers_count":21,"open_issues_count":1,"forks_count":6,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-30T21:33:56.147Z","etag":null,"topics":["cassandra","javascript","mongodb","mongoose","nodejs"],"latest_commit_sha":null,"homepage":"https://stargate.io","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stargate.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-12-16T21:33:01.000Z","updated_at":"2025-02-21T13:51:35.000Z","dependencies_parsed_at":null,"dependency_job_id":"e40c7353-7d43-4bac-a711-32aa6793c6db","html_url":"https://github.com/stargate/stargate-mongoose","commit_stats":{"total_commits":106,"total_committers":3,"mean_commits":"35.333333333333336","dds":0.160377358490566,"last_synced_commit":"8266c3f414ce7578d2b800464e99bd823815d90c"},"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stargate%2Fstargate-mongoose","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stargate%2Fstargate-mongoose/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stargate%2Fstargate-mongoose/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stargate%2Fstargate-mongoose/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stargate","download_url":"https://codeload.github.com/stargate/stargate-mongoose/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252126421,"owners_count":21698963,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cassandra","javascript","mongodb","mongoose","nodejs"],"created_at":"2024-11-12T20:23:35.380Z","updated_at":"2025-05-03T00:30:59.569Z","avatar_url":"https://github.com/stargate.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# stargate-mongoose ![ci-tests](https://github.com/stargate/stargate-mongoose/actions/workflows/ci-tests.yml/badge.svg)\n\n`stargate-mongoose` is a Mongoose driver for [Data API](https://github.com/stargate/data-api) which runs on top of Apache Cassandra / DataStax Enterprise.\n\n1. [Quickstart](#quickstart)\n2. [Architecture](#architecture)\n3. [Version compatibility](#version-compatibility)\n4. [Connecting to AstraDB](#connecting-to-astradb)\n5. [Sample Applications](#sample-applications)\n6. [Features](#features)\n7. [NodeJS MongoDB Driver Overriding (experimental)](#nodejs-mongodb-driver-overriding-experimental)\n8. [API Reference](APIReference.md)\n9. [Developer Guide](DEVGUIDE.md)\n\n## Quickstart\nPrerequisites:\nnode (\u003e=14.0.0), npm/yarn, Docker (for testing the sample app locally using docker compose)\n- Start `Docker` on your local machine.\n- Clone this repository\n```shell\ngit clone https://github.com/stargate/stargate-mongoose.git\ncd stargate-mongoose\n```\n- Execute below script and wait for it to complete, which starts a simple Data API on local with a DSE 6.8 (DataStax Enterprise) as database backend.\n\nFor macOS/Linux\n```shell\nbin/start_data_api.sh\n```\nFor Windows\n```shell\nbin\\start_data_api.cmd\n```\n- Create a sample project called 'sample-app'\n```shell\nmkdir sample-app\ncd sample-app\n```\n- Initialize and add required dependencies\n```shell\nnpm init -y \u0026\u0026 npm install express mongoose stargate-mongoose --engine-strict\n```\nOR\n```shell\nyarn init -y \u0026\u0026 yarn add express mongoose stargate-mongoose\n```\n\n\n- Create a file called `index.js` under the 'sample-app' directory and copy below code into the file.\n```typescript\n//imports\nconst express = require('express');\nconst mongoose = require('mongoose');\nconst stargate_mongoose = require('stargate-mongoose');\nconst Schema = mongoose.Schema;\nconst driver = stargate_mongoose.driver;\n\n//override the default native driver\nmongoose.setDriver(driver);\n\n//Set up mongoose \u0026 end points definition\nconst Product = mongoose.model('Product', new Schema({ name: String, price: Number }));\nmongoose.connect('http://localhost:8181/v1/inventory', {\n    username: 'cassandra',\n    password: 'cassandra'\n});\nObject.values(mongoose.connection.models).map(Model =\u003e Model.init());\nconst app = express();\napp.get('/addproduct', (req, res) =\u003e {\n    const newProduct = new Product(\n        {\n            name: 'product' + Math.floor(Math.random() * 99 + 1),\n            price: '' + Math.floor(Math.random() * 900 + 100)\n        });\n    newProduct.save();\n    res.send('Added a product!');\n});\napp.get('/getproducts', (req, res) =\u003e {\n    Product.find()\n        .then(products =\u003e res.json(products));\n});\n\n//Start server\nconst HOST = '0.0.0.0';\nconst PORT = 8097;\napp.listen(PORT, HOST, () =\u003e {\n    console.log(`Running on http://${HOST}:${PORT}`);\n    console.log('http://localhost:' + PORT + '/addproduct');\n    console.log('http://localhost:' + PORT + '/getproducts');\n});\n```\n- Execute below to run the app \u0026 navigate to the urls listed on the console\n```shell\nnode index.js\n```\n\n- Stop the Data API once the test is complete\n```shell\ndocker compose -f bin/docker-compose.yml down -v\n```\n\n## Architecture\n### High level architecture\n\u003cimg src=\"stargate-mongoose-arch.png\" alt=\"stargate-mongoose usage end to end architecture\"/\u003e\n\n### Components\n- Cassandra Cluster - Apache Cassandra / DataStax Enterprise Cluster as backend database.\n- Stargate Coordinator Nodes - [Stargate](https://stargate.io/) is an open source Data API Gateway for Cassandra. Coordinator is one of the primary components of Stargate which connects the API layer to the backend database. More details can be found [here](https://stargate.io/docs/latest/concepts/concepts.html#stargate-v2-0).\n- Stargate Data API - [Data API](https://github.com/stargate/data-api) is an open source Data API that runs on top of Stargate's coordinator.\n- JavaScript Clients that use Mongoose - Mongoose is an elegant mongodb object modeling library for node.js applications. By implementing a driver required by the Mongoose interface to connect to the Data API instead of native mongodb access layer, now a JavaScript client can store/retrieve documents on an Apache Cassandra/DSE backend.\n\nThe current implementation of the Data API uses DataStax Enterprise (DSE) as the backend database.\n\n## Version compatibility\n| Component/Library Name | Version            |\n|------------------------|--------------------|\n| Mongoose               | ^7.5.0 \\|\\| ^8.0.0 |\n| data-api               | 1.x                |\n| DataStax Enterprise    | 6.8.x              |\n\nCI tests are run using the Stargate and Data API versions specified in the [api-compatibility.versions](api-compatibility.versions) file.\n\n## Connecting to AstraDB\n\nHere's a quick way to connect to AstraDB using `stargate-mongoose` driver.\n\n```typescript\nconst mongoose = require(\"mongoose\");\nconst { driver, createAstraUri } = require(\"stargate-mongoose\");\n\nconst uri = createAstraUri(\n  process.env.ASTRA_DB_API_ENDPOINT,\n  process.env.ASTRA_DB_APPLICATION_TOKEN,\n  process.env.ASTRA_DB_NAMESPACE // optional\n);\n\nmongoose.setDriver(driver);\n\nawait mongoose.connect(uri, {\n  isAstra: true,\n});\n```\n\nAnd the step-by-step instructions with a sample application can be found here in below guide.\n\nhttps://docs.datastax.com/en/astra/astra-db-vector/api-reference/data-api-with-mongoosejs.html\n\n## Sample Applications\n\nSample applications developed using `stargate-mongoose` driver are available in below repository.\n\nhttps://github.com/stargate/stargate-mongoose-sample-apps\n\n## Features\n\n### Connection APIs\n| \u003cnobr\u003eOperation Name\u003c/nobr\u003e | Description                                                                                                                                           |\n|-----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|\n| createDatabase              | When flag `createNamespaceOnConnect` is set to `true` the keyspace passed on to the `mongoose.connect` function via the URL, is created automatically |\n| dropDatabase                | Drops the database                                                                                                                                    |\n| createCollection            | `mongoose.model('ModelName',modelSchema)` creates a collection as required                                                                            |\n| dropCollection              | `model.dropCollection()` drops the collection                                                                                                         |\n\n\n### Collection APIs\n| \u003cnobr\u003eOperation Name\u003c/nobr\u003e | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |\n|-----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| countDocuments              | `Model.countDocuments(filter)` returns the count of documents                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |\n| deleteMany                  | `Model.deleteMany(filter)`. This API will throw an error when more than 20 records are found to be deleted.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |\n| deleteOne                   | `Model.deleteOne(filter, options)` options - `sort`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |\n| find                        | `Model.find(filter, projection, options)`  options - `limit`, `pageState`, `skip`, `sort` (skip works only with sorting)                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |\n| findOne                     | `Model.findOne(filter, options)` options - `sort` Example: `findOne({}, { sort: { username: -1 } })`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |\n| findOneAndDelete            | `Model.findOneAndDelete(filter, options)` options - `sort`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |\n| findOneAndReplace           | `Model.findOneAndReplace(filter, replacement, options)`\u003cbr\u003e__options__\u003cbr\u003e` upsert:` (default `false`)\u003cbr\u003e`true` - if a document is not found for the given filter, a new document will be inserted with the values in the filter (eq condition) and the values in the `$set` and `$setOnInsert`operators.\u003cbr\u003e`false` - new document will not be inserted when no match is found for the given filter\u003cbr/\u003e--------\u003cbr/\u003e`returnDocument`: (default `before`)\u003cbr/\u003e`before` - Return the document before the changes were applied\u003cbr/\u003e`after` - Return the document after the changes are applied |\n| findOneAndUpdate            | `Model.findOneAndUpdate(filter, update, options)`\u003cbr\u003e__options__\u003cbr\u003e` upsert:` (default `false`)\u003cbr\u003e`true` - if a document is not found for the given filter, a new document will be inserted with the values in the filter (eq condition) and the values in the `$set` and `$setOnInsert`operators.\u003cbr\u003e`false` - new document will not be inserted when no match is found for the given filter\u003cbr/\u003e--------\u003cbr/\u003e`returnDocument`: (default `before`)\u003cbr/\u003e`before` - Return the document before the changes were applied\u003cbr/\u003e`after` - Return the document after the changes are applied       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |\n| insertMany                  | `Model.insertMany([{docs}], options)` In a single call, only 20 records can be inserted. options - `ordered`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |\n| insertOne                   | `Model.insertOne({doc})`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |\n| updateMany                  | `Model.updateMany(filter, update, options)`\u003cbr/\u003e__options__\u003cbr\u003e` upsert:` (default `false`)\u003cbr\u003e`true` - if a document is not found for the given filter, a new document will be inserted with the values in the filter (eq condition) and the values in the `$set` and `$setOnInsert`operators.\u003cbr\u003e`false` - new document will not be inserted when no match is found for the given filter\u003cbr\u003e\u003cbr/\u003e** _This API will throw an error when more than 20 records are found to be updated._                                                                                                        |\n| updateOne                   | `Model.updateOne(filter, update, options)`\u003cbr\u003e__options__\u003cbr\u003e` upsert:` (default `false`)\u003cbr\u003e`true` - if a document is not found for the given filter, a new document will be inserted with the values in the filter (eq condition) and the values in the `$set` and `$setOnInsert`operators.\u003cbr\u003e`false` - new document will not be inserted when no match is found for the given filter\u003cbr/\u003e--------\u003cbr/\u003e`returnDocument`: (default `before`)\u003cbr/\u003e`before` - Return the document before the changes were applied\u003cbr/\u003e`after` - Return the document after the changes are applied              |\n\n### Filter Clause\n| Operator           | Description                                                                                                                                                    |\n|--------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| literal comparison | Equal to. Example: `{ 'first_name' : 'jim' }`                                                                                                                  |\n| $eq                | Example: `{ 'first_name' : { '$eq' : 'jim' } }`                                                                                                                |\n| $gt                | Example (age \u003e 25): `{ 'age' : { '$gt' : 25 } }`                                                                                                |\n| $gte               | Example (age \u003e= 25): `{ 'age' : { '$gte' : 25 } }`                                                                                              |\n| $lt                | Example (age \u003c 25): `{ 'age' : { '$lt' : 25 } }`                                                                                                |\n| $lte               | Example (age \u003c= 25): `{ 'age' : { '$lte' : 25 } }`                                                                                              |\n| $ne                | Example: `{ 'first_name' : { '$ne' : 'jim' } }`                                                                                   |\n| $in                | Example: `{ '_id' : { '$in' : ['nyc', 'la'] } }` $in is not supported in non _id columns at the moment                                                         |\n| $nin               | Example: `{ 'address.city' : { '$nin' : ['nyc', 'la'] } }`                                                                                      |\n| $not               | Not supported. Example: `{ 'first_name' : { '$not' : { '$eq' : 'jim' }}}`                                                                                      |\n| $exists            | Example: `{ 'address.city' : { '$exists' : true} }`                                                                                                            |\n| $all               | Array operation. Matches if all the elements of an array matches the given values. Example: `{ 'tags' : { '$all' : [ 'home', 'school' ] } }`                   |\n| $elemMatch         | Not supported. Matches if the elements of an array in a document matches the given conditions. Example: `{'goals': { '$elemMatch': { '$gte': 2, '$lt': 10 }}}` |\n| $size              | Array Operation. Example: `{ 'tags' : { '$size' : 1 } }`                                                                                                       |\n| $and (implicit)    | Logical expression. Example : ` { '$and' : [ {first_name : 'jim'}, {'age' : {'$gt' : 25 } } ] } `                                                              |\n| $and (explicit)    | Example : ` { '$and' : [ {first_name : 'jim'}, {'age' : {'$gt' : 25 } } ] } `                                                                   |\n| $or                | Example: `{ '$or' : [ {first_name : 'jim'}, {'age' : {'$gt' : 25 } } ] }`                                                                                                                                              |\n\n### Projection Clause\n| Operator                | Description                                                                                                                      |\n|-------------------------|----------------------------------------------------------------------------------------------------------------------------------|\n| $elemMatch (projection) | Not supported                                                                                                                    |\n| $slice                  | Array related operation. Example: `{ 'tags' : { '$slice': 1 }}` returns only the first element from the array field called tags. |\n| $ (projection)          | Example: Model.find({}, { username : 1, _id : 0}) - This returns username in the response and the _id field                      |\n\n### Sort Clause\n| Operator          | Description   |\n|-------------------|---------------|\n| Single Field Sort | Supported     |\n| Multi Field Sort  | Not supported |\n\n### Update Clause\n| Operator     | Description                                                                                                                                                                       |\n|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| $inc         | Example: `{ '$inc': { 'points' : 5 } }`                                                                                                                                           |\n| $min         | Example: `{ 'col': { '$min' : 5 } }` if the columns value is greater than 5, it will be updated with 5                                                                            |\n| $max         | Example: `{ 'col': { '$max' : 50 } }` if the columns value is lesser than 50, it will be updated with 50                                                                          |\n| $rename      | Example: `{ $rename: { '$max' : 50 } }` if the columns value is lesser than 50, it will be updated with 50                                                                        |\n| $set         | Example: `{'update' : {'$set': {'location': 'New York'} }}`                                                                                                                       |\n| $setOnInsert | Example: `{'update' : {'$set': {'location': 'New York'}, '$setOnInsert': {'country': 'USA'} }}`                                                                                   |\n| $unset       | Example: `{'update' : {'$unset': [address.location] }}`                                                                                                                           |\n| $addToSet    | Example: `{'$addToSet' : {'points': 10}}`. This will add 10 to an array called `points` in the documents, without duplicates (i.e. ll skip if 10 is already present in the array) |\n| $pop         | Example: `{'$pop' : {'points': 1 }}`. This removes the last 1 item from an array called `points`. -1 will remove the first 1 item.                                                |\n| $pull        | Not supported                                                                                                                                                                     |\n| $push        | Example. `'$push': {'tags': 'work'}`. This pushes an element called `work` to the array `tags`                                                                                    |\n| $pullAll     | Not supported                                                                                                                                                                     |\n\n\n### Index Operations\n\nIndex operations are not supported. There is one caveat for `ttl` indexes: When adding a document, you can add a `ttl` option (determined in seconds) that will behave in the similar way to a `ttl` index. For example, with the collection's client:\n\n```javascript\nimport { Client } from 'stargate-mongoose';\n// connect to Data API\nconst client = await Client.connect(process.env.DATA_API_URI);\n// get a collection\nconst collection = client.db().collection('docs');\n// insert and expire this document in 10 seconds\nawait collection.insertOne({ hello: 'world' }, { ttl: 10 });\n```\n\n### Aggregation Operations\n\nAggregation operations are not supported.\n\n### Transaction Operations\n\nTransaction operations are not supported.\n\n## NodeJS MongoDB Driver Overriding (experimental)\n\nIf you have an application that uses the NodeJS MongoDB driver, or a dependency that uses the NodeJS MongoDB driver, it is possible to override its use with the collections package of `stargate-mongoose`. This makes your application use Data API documents instead of MongoDB documents. Doing so requires code changes in your application that address the features section of this README, and a change in how you set up your client connection.\n\nIf your application uses `mongodb` you can override its usage like so:\n\nIn your app's `mongodb` `package.json` entry:\n\n```\n\"mongodb\": \"stargate-mongoose@0.2.0-ALPHA-3\",\n```\n\nThen, re-install your dependencies\n\n```bash\nnpm i\n```\n\nFinally, modify your connection so that your driver connects to Data API\n\n```javascript\nimport { MongoClient } from 'stargate-mongoose';\n\n// connect to Data API\nconst client = await MongoClient.connect(process.env.DATA_API_URI);\n```\n\nIf you have an application dependency that uses `mongodb`, you can override its usage like so (this example uses `mongoose`):\n\nAdd an override to your app's `package.json` (requires NPM 8.3+), also, add `stargate-mongoose as a dependency:\n\n```\n\"dependencies\": {\n    \"stargate-mongoose\": \"^0.2.0-ALPHA-3\"\n},\n\"overrides\": {\n    \"mongoose\": {\n        \"mongodb\":  \"stargate-mongoose@0.2.0-ALPHA-3\"\n    }\n},\n```\n\nThen, re-install your dependencies\n\n```bash\nnpm i\n```\n\nFinally, modify your dependencies connection so that your driver connects to Data API\n\n```javascript\nimport mongoose from 'mongoose';\n\n// connect to Data API\nawait mongoose.connect(process.env.DATA_API_URI);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstargate%2Fstargate-mongoose","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstargate%2Fstargate-mongoose","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstargate%2Fstargate-mongoose/lists"}