### Install sails-mongo Adapter Source: https://github.com/balderdashy/sails-mongo/blob/master/README.md Install the sails-mongo adapter using npm. This command should be run in your project's root directory. ```bash npm install sails-mongo ``` -------------------------------- ### Default Datastore Configuration Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/07-configuration-reference.md Configure the default MongoDB datastore in `config/datastores.js`. This example sets up a local MongoDB instance. ```javascript module.exports.datastores = { default: { adapter: 'sails-mongo', url: 'mongodb://localhost:27017/my_database' } }; ``` -------------------------------- ### Production Configuration (MongoDB Atlas) Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/07-configuration-reference.md Example configuration for connecting to MongoDB Atlas in a production environment, including connection pooling and timeouts. ```javascript module.exports.datastores = { default: { adapter: 'sails-mongo', url: 'mongodb+srv://username:password@cluster.mongodb.net/production_db?retryWrites=true&w=majority', poolSize: 25, maxPoolSize: 50, connectTimeoutMS: 10000, socketTimeoutMS: 45000, serverSelectionTimeoutMS: 5000, retryWrites: true } }; ``` -------------------------------- ### Registering a MongoDB Datastore with Sails Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/02-lifecycle-methods.md This example demonstrates how to configure and load a MongoDB datastore using the sails-mongo adapter. Ensure the `adapter` is set to 'sails-mongo' and provide a valid MongoDB connection `url`. ```javascript const sails = require('sails'); sails.load({ datastores: { default: { adapter: 'sails-mongo', url: 'mongodb://localhost:27017/my_app', ssl: true, poolSize: 10 } } }, (err) => { if (err) return console.error(err); // Connection established }); ``` -------------------------------- ### Waterline Model Usage Examples Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/03-dml-methods.md These examples demonstrate standard Waterline model methods that are automatically handled by sails-mongo. They cover creating single or multiple records, updating existing records, and destroying records. ```javascript const user = await User.create({ email: 'john@example.com' }); ``` ```javascript const users = await User.createEach([{ email: 'john@example.com' }, { email: 'jane@example.com' }]); ``` ```javascript const updated = await User.update({ id: 1 }).set({ name: 'Updated Name' }); ``` ```javascript const deleted = await User.destroy({ id: 1 }); ``` -------------------------------- ### Direct Collection Access in Sails-Mongo Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/06-connection-management.md Demonstrates how to get a database instance and a collection reference using the connection manager, allowing direct use of MongoDB driver methods. ```javascript const adapter = require('sails-mongo'); const manager = adapter.datastores['default'].manager; // Get database instance const db = manager.db(); // Get collection reference const usersCollection = db.collection('users'); // Now use MongoDB driver methods directly usersCollection.findOne({ email: 'john@example.com' }, (err, user) => { if (err) return console.error(err); console.log(user); }); ``` -------------------------------- ### Implementing Transactions in Sails-Mongo Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/06-connection-management.md Provides an example of how to perform atomic transactions, such as fund transfers, using sessions and the `withTransaction` method. This requires a MongoDB replica set. ```javascript const adapter = require('sails-mongo'); const manager = adapter.datastores['default'].manager; // Start a session const session = manager.startSession(); async function transferFunds() { try { await session.withTransaction(async () => { const db = manager.db(); // Debit from account A await db.collection('accounts') .updateOne( { _id: accountA }, { $inc: { balance: -100 } }, { session } ); // Credit to account B await db.collection('accounts') .updateOne( { _id: accountB }, { $inc: { balance: 100 } }, { session } ); }); } finally { await session.endSession(); } } ``` -------------------------------- ### Storing and Retrieving Buffers/Binary Data Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/08-types-and-errors.md Illustrates how to store binary data using the 'ref' or 'json' type in Waterline models and how to retrieve it as a Buffer. The example shows creating a buffer and saving it to a model, then verifying its type upon retrieval. ```javascript // In model attributes: { image: { type: 'ref' }, // Or 'json' for flexibility hash: { type: 'string' } // Store as hex or base64 } // Store buffer const buffer = Buffer.from('binary data'); await File.create({ name: 'file.bin', data: buffer }); // Retrieve buffer const file = await File.findOne('file.bin'); console.log(Buffer.isBuffer(file.data)); // true ``` -------------------------------- ### Batch Process Documents with Sails-Mongo Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/09-advanced-usage.md Efficiently update large datasets by processing documents in batches. This example finds unprocessed documents and updates them in chunks, marking them as processed. ```javascript const adapter = require('sails-mongo'); const collection = adapter.datastores['default'].manager.db().collection('users'); async function processBatch(batchSize = 1000) { const cursor = collection.find({ processed: false }); let batch = []; for await (const doc of cursor) { batch.push(doc._id); if (batch.length === batchSize) { // Process batch await collection.updateMany( { _id: { $in: batch } }, { $set: { processed: true, processedAt: new Date() } } ); console.log(`Processed ${batch.length} documents`); batch = []; } } // Process remaining if (batch.length > 0) { await collection.updateMany( { _id: { $in: batch } }, { $set: { processed: true, processedAt: new Date() } } ); console.log(`Processed ${batch.length} remaining documents`); } } processBatch(5000).catch(console.error); ``` -------------------------------- ### Waterline DQL Method Usage Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/04-dql-methods.md Examples of using Waterline's ORM methods to perform find, count, sum, and average operations. Waterline automatically translates these calls into stage-3 queries and processes the results. ```javascript const users = await User.find({ status: 'active' }).sort('name ASC').limit(10); const count = await User.count({ status: 'active' }); const total = await Order.sum('amount').where({ status: 'completed' }); const avg = await Product.avg('price').where({ category: 'electronics' }); ``` -------------------------------- ### MongoDB Authentication Error Example Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/08-types-and-errors.md Illustrates an authentication error from MongoDB. This can occur due to incorrect credentials, insufficient user permissions, or an incorrect authSource. Verify your username, password, and authSource. ```javascript { name: 'MongoAuthenticationError', message: '[AuthenticationFailed] authentication failed', code: 'MongoError' } ``` -------------------------------- ### Create Migration Pattern Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/05-ddl-methods.md Use `migrate: 'create'` to define physical models (collections) on startup. This pattern is suitable for development environments. ```javascript // config/migrations.js module.exports.datastores = { default: { migrate: 'create' // Create collections on startup } }; ``` -------------------------------- ### MongoDB Validation Error Example Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/08-types-and-errors.md An example of a MongoDB validation error, which occurs when document schema validation fails. This is typically not used with Sails.js. ```javascript { name: 'MongoError', message: 'Document failed validation', code: 121 } ``` -------------------------------- ### Get Collection Information - Sails-Mongo Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/05-ddl-methods.md Use these methods to retrieve information about existing collections in your MongoDB database via Sails-Mongo. This includes listing all collections, getting statistics for a specific collection, and inspecting its indexes. ```javascript const adapter = require('sails-mongo'); const db = adapter.datastores['default'].manager; // List all collections db.listCollections().toArray((err, collections) => { if (err) return console.error(err); collections.forEach(c => console.log(c.name)); }); // Get collection stats db.collection('users').stats((err, stats) => { if (err) return console.error(err); console.log('Document count:', stats.count); console.log('Average document size:', stats.avgObjSize, 'bytes'); }); // Get index information db.collection('users').getIndexes((err, indexes) => { if (err) return console.error(err); console.log('Indexes:', indexes); }); ``` -------------------------------- ### Pagination with Limit and Skip Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/04-dql-methods.md Demonstrates how to implement pagination using the `limit` and `skip` parameters within the `criteria` object for the `find` method. This allows fetching data in chunks. ```javascript adapter.find('default', { using: 'users', criteria: { where: { status: 'active' }, limit: 10, // Page size skip: 20, // Offset: (page - 1) * pageSize = (3 - 1) * 10 = 20 sort: [['created_at', 'DESC']] }, meta: {} }, (err, page) => { // Returns items 21-30 }); ``` -------------------------------- ### Low-Level Adapter Call for createEach Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/03-dml-methods.md Directly call the adapter's createEach method for more control. Specify the datastore, collection, values, and whether to fetch created records. The callback handles success or error. ```javascript // Low-level adapter call adapter.createEach('default', { using: 'users', values: [ { email: 'john@example.com', name: 'John' }, { email: 'jane@example.com', name: 'Jane' } ], meta: { fetch: true } }, (err, users) => { if (err) return console.error(err); console.log('Created:', users.length, 'records'); }); ``` -------------------------------- ### Drop Migration Pattern Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/05-ddl-methods.md Use `migrate: 'drop'` to drop all existing collections and recreate them on startup. This is useful for resetting the database during development. ```javascript // config/migrations.js module.exports.datastores = { default: { migrate: 'drop' // Drop all collections on startup } }; ``` -------------------------------- ### Lifecycle & Connection Methods Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/00-index.md Methods related to adapter lifecycle management, datastore registration, and connection handling. ```APIDOC ## Lifecycle & Connection ### `adapter.registerDatastore(config, models, callback)` Registers a datastore with the adapter. ### `adapter.teardown(name, callback)` Tears down a datastore connection. ### `adapter.createManager(url, onFailure, meta)` Creates a MongoDB connection manager. ### `adapter.destroyManager(manager)` Destroys a MongoDB connection manager. ### `adapter.getConnection(manager, meta)` Gets a connection from the manager. ### `adapter.releaseConnection(connection)` Releases a connection back to the manager. ### `adapter.datastores` Registry of connected datastores. ### `adapter.mongodb` Direct reference to the MongoDB driver. ``` -------------------------------- ### Fix Invalid Connection String Scheme Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/07-configuration-reference.md Corrects a 'MongoParseError: Invalid scheme' by ensuring the MongoDB connection URL starts with 'mongodb://' or 'mongodb+srv://'. ```javascript // WRONG url: 'mongodb:localhost:27017/db' // CORRECT url: 'mongodb://localhost:27017/db' ``` -------------------------------- ### Low-level adapter call to create a record Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/03-dml-methods.md Use this low-level adapter call for direct database interaction. It requires specifying the datastore name, collection, values, and optionally a fetch flag. The callback receives an error or the newly created record. ```javascript adapter.create('default', { using: 'users', values: { email: 'john@example.com', name: 'John' }, meta: { fetch: true } }, (err, newUser) => { if (err) return console.error(err); console.log('Created:', newUser); // { _id: ObjectID(...), email: '...', name: '...' } }); ``` -------------------------------- ### Get MongoDB Client - Sails-Mongo Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/09-advanced-usage.md Access the underlying MongoDB driver manager and database client from the sails-mongo adapter. This is useful for performing operations not directly supported by Waterline. ```javascript const adapter = require('sails-mongo'); const mongoClient = adapter.datastores['default'].manager; const db = mongoClient.db(); // Now use MongoDB driver directly const collection = db.collection('users'); ``` -------------------------------- ### Configure Production SSL Certificates Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/07-configuration-reference.md Sets up secure connections using proper SSL certificates for production environments by specifying the certificate authority file and client key file. ```javascript { adapter: 'sails-mongo', url: 'mongodb://host:27017/db', tls: true, tlsCAFile: '/etc/ssl/certs/ca.pem', tlsCertificateKeyFile: '/etc/ssl/certs/client.pem' } ``` -------------------------------- ### Geospatial Queries - Sails-Mongo Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/09-advanced-usage.md Perform geospatial queries to find documents based on location. This example demonstrates creating a 2dsphere index and querying for documents near a specific point. ```javascript const adapter = require('sails-mongo'); const collection = adapter.datastores['default'].manager.db().collection('stores'); // Create 2dsphere index await collection.createIndex({ location: '2dsphere' }); // Find stores near a point const nearby = await collection.find({ location: { $near: { $geometry: { type: 'Point', coordinates: [-73.97, 40.77] // [longitude, latitude] }, $maxDistance: 5000 // 5km in meters } } }).toArray(); console.log('Nearby stores:', nearby); ``` -------------------------------- ### Development Configuration (Local MongoDB) Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/07-configuration-reference.md Use this configuration for local development with a MongoDB instance running on the default port. ```javascript module.exports.datastores = { default: { adapter: 'sails-mongo', url: 'mongodb://localhost:27017/my_app_dev' } }; ``` -------------------------------- ### Configure Test Datastore Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/07-configuration-reference.md Set up an isolated MongoDB datastore for testing purposes. Ensures a fresh database schema for each test run by using the 'drop' migration strategy. ```javascript // config/env/test.js module.exports.datastores = { default: { adapter: 'sails-mongo', url: 'mongodb://localhost:27017/my_app_test', migrate: 'drop' // Fresh schema for each test run } }; ``` -------------------------------- ### Low-Level Adapter Find Call Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/04-dql-methods.md Directly call the adapter's `find` method for data retrieval. Requires datastore name, query object, and a callback function. ```javascript adapter.find('default', { using: 'users', criteria: { where: { status: 'active' }, limit: 10, skip: 0, sort: [['name', 'ASC']] }, meta: {} }, (err, users) => { if (err) return console.error(err); console.log('Found:', users.length, 'users'); console.log(users); }); ``` -------------------------------- ### Aggregation Pipeline - Sails-Mongo Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/09-advanced-usage.md Execute complex data transformations using MongoDB's aggregation framework. This example demonstrates grouping, sorting, and calculating aggregate values from 'orders' collection. ```javascript const adapter = require('sails-mongo'); const db = adapter.datastores['default'].manager.db(); // Get total sales by category const results = await db.collection('orders').aggregate([ { $match: { status: 'completed', createdAt: { $gte: new Date('2023-01-01') } } }, { $group: { _id: '$category', total: { $sum: '$amount' }, count: { $sum: 1 }, average: { $avg: '$amount' } } }, { $sort: { total: -1 } } ]).toArray(); console.log(results); // [ // { _id: 'electronics', total: 5000, count: 10, average: 500 }, // { _id: 'books', total: 300, count: 15, average: 20 } // ] ``` -------------------------------- ### Monitor Collection Changes with Change Streams Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/09-advanced-usage.md Utilize MongoDB change streams to observe real-time modifications to collections. This example shows how to listen for insert, update, and delete operations on an 'orders' collection. ```javascript const adapter = require('sails-mongo'); const collection = adapter.datastores['default'].manager.db().collection('orders'); const changeStream = collection.watch(); changeStream.on('change', (change) => { console.log('Change detected:', change); switch (change.operationType) { case 'insert': console.log('New order:', change.fullDocument); break; case 'update': console.log('Order updated:', change.updateDescription.updatedFields); break; case 'delete': console.log('Order deleted:', change.documentKey._id); break; } }); changeStream.on('error', (err) => { console.error('Change stream error:', err); }); // When done // changeStream.close(); ``` -------------------------------- ### Correct Connection Handling and Release Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/06-connection-management.md This snippet shows the correct method for handling database connections, ensuring they are released after use to prevent memory leaks. Always release connections in the success callback. ```javascript // CORRECT - connection is released driver.getConnection({ manager }).switch({ success: (report) => { // Use connection // Always release driver.releaseConnection({ connection: report.connection }).switch({ success: () => console.log('Released'), error: (err) => console.error(err) }); } }); ``` -------------------------------- ### MongoDB Network Error Example Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/08-types-and-errors.md Represents a network error when connecting to MongoDB. Causes include the server not running, incorrect host/port, or firewall issues. Ensure MongoDB is running and connection details are correct. ```javascript { name: 'MongoNetworkError', message: 'connect ECONNREFUSED 127.0.0.1:27017', code: 'ECONNREFUSED' } ``` -------------------------------- ### Lifecycle Methods Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/01-adapter-overview.md Methods for managing the datastore lifecycle, including registration and teardown. ```APIDOC ## Lifecycle Methods - `registerDatastore(dsConfig, physicalModelsReport, done)` — Register a new datastore - `teardown(datastoreName, done)` — Unregister a datastore ``` -------------------------------- ### Generate Monthly Sales Report using Aggregation Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/09-advanced-usage.md Create a monthly sales report by matching completed orders, grouping them by year and month, summing amounts, and sorting the results. This demonstrates multiple aggregation stages. ```javascript const report = await db.collection('orders').aggregate([ { $match: { status: 'completed' } }, { $group: { _id: { year: { $year: '$createdAt' }, month: { $month: '$createdAt' } }, total: { $sum: '$amount' }, count: { $sum: 1 } } }, { $sort: { '_id.year': 1, '_id.month': 1 } } ]).toArray(); ``` -------------------------------- ### Count Records Matching Criteria Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/04-dql-methods.md Use `count` to get the number of documents that match a specific filter. This method is efficient for large datasets and does not return the documents themselves. It can be used via Waterline ORM or directly with the adapter. ```javascript // Using Waterline const activeCount = await User.count({ status: 'active' }); console.log('Active users:', activeCount); ``` ```javascript // Low-level adapter call adapter.count('default', { using: 'users', criteria: { where: { status: 'active' }, limit: 9007199254740991, skip: 0, sort: [] }, meta: {} }, (err, count) => { if (err) return console.error(err); console.log('Count:', count); }); ``` -------------------------------- ### MongoDB Timeout Error Example Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/08-types-and-errors.md Represents a timeout error when interacting with MongoDB. Causes include a slow server, network latency, or an exhausted connection pool. Adjusting connection and server selection timeouts may help. ```javascript { name: 'MongoTimeoutError', message: 'Server selection timed out after 30000 ms' } ``` -------------------------------- ### Bulk Operations - Sails-Mongo Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/09-advanced-usage.md Perform multiple insert, update, or delete operations efficiently using MongoDB's bulk operations API. This example updates existing documents, removes others, and inserts a new one. ```javascript const adapter = require('sails-mongo'); const collection = adapter.datastores['default'].manager.db().collection('users'); const bulk = collection.initializeUnorderedBulkOp(); bulk.find({ status: 'pending' }).update({ $set: { status: 'processing' } }); bulk.find({ status: 'old' }).remove(); bulk.insert({ name: 'New User', status: 'active' }); const result = await bulk.execute(); console.log('Matched:', result.nMatched); console.log('Modified:', result.nModified); console.log('Deleted:', result.nRemoved); console.log('Inserted:', result.nInserted); ``` -------------------------------- ### Adapter Entry Point Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/01-adapter-overview.md This shows how to require and use the sails-mongo adapter in your Sails.js/Waterline application. ```APIDOC ## Entry Point ```javascript require('sails-mongo') ``` The adapter exports a single object (exported at `lib/index.js`) that implements the Waterline adapter interface. ``` -------------------------------- ### Performing Bulk Operations with Sails-Mongo Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/06-connection-management.md Shows how to initialize and execute unordered bulk operations on a MongoDB collection using the connection manager. ```javascript const adapter = require('sails-mongo'); const manager = adapter.datastores['default'].manager; const collection = manager.db().collection('orders'); // Create a bulk operation const bulk = collection.initializeUnorderedBulkOp(); // Queue multiple operations bulk.find({ status: 'pending' }).update({ $set: { status: 'processing' } }); bulk.find({ status: 'old' }).removeOne(); bulk.insert({ status: 'new', amount: 100 }); // Execute all at once bulk.execute((err, result) => { if (err) return console.error(err); console.log('Matched:', result.nMatched); console.log('Modified:', result.nModified); }); ``` -------------------------------- ### Paginate Records with Skip and Limit Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/00-index.md Use `skip` and `limit` to implement pagination for fetching subsets of records. Ensure `sort` is applied for consistent pagination results. ```javascript const page = 2; const pageSize = 10; const users = await User.find() .skip((page - 1) * pageSize) .limit(pageSize) .sort('createdAt DESC'); ``` -------------------------------- ### create Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/03-dml-methods.md Creates a single new record in the database. It can optionally return the created record. ```APIDOC ## create ### Description Creates a single new record in the database. It can optionally return the created record. ### Method `adapter.create(datastoreName, s3q, done)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - `datastoreName` (String) - Required - Identity of datastore to use - `s3q` (Object) - Required - Stage-3 query object - `using` (String) - Required - Collection name - `values` (Object) - Required - Attribute values for new record - `meta.fetch` (Boolean) - Optional - If `true`, return created record; if `false` (default), return undefined ### Request Example ```javascript // Using Waterline model (typical usage) await User.create({ email: 'john@example.com', name: 'John' }); // Low-level adapter call adapter.create('default', { using: 'users', values: { email: 'john@example.com', name: 'John' }, meta: { fetch: true } }, (err, newUser) => { if (err) return console.error(err); console.log('Created:', newUser); // { _id: ObjectID(...), email: '...', name: '...' } }); ``` ### Response #### Success Response Calls `done(null, createdRecord)` on success. `createdRecord` is the newly created record if `meta.fetch` was true, otherwise `undefined`. #### Response Example ```json { "_id": "ObjectID(...)", "email": "john@example.com", "name": "John" } ``` ### Errors - `E_UNIQUE` — Unique constraint violation on any field marked unique - Standard MongoDB errors (connection failure, validation, etc.) ``` -------------------------------- ### Calculate Average Price using Waterline Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/04-dql-methods.md Demonstrates how to use the Waterline ORM to calculate the average price of products in the 'electronics' category. This is a high-level abstraction. ```javascript // Using Waterline const avgPrice = await Product.avg('price').where({ category: 'electronics' }); console.log('Average price:', avgPrice); ``` -------------------------------- ### Configure SSL/TLS for Production Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/06-connection-management.md Secure your MongoDB connections in production environments by enabling TLS/SSL. Configure certificate validation and provide paths to certificate files and passwords as needed. ```javascript { datastores: { production: { adapter: 'sails-mongo', url: 'mongodb+srv://user:pass@cluster.mongodb.net/dbname', // TLS/SSL options tls: true, tlsAllowInvalidCertificates: false, tlsAllowInvalidHostnames: false, tlsCAFile: '/path/to/ca.pem', tlsCertificateKeyFile: '/path/to/client.pem', tlsCertificateKeyFilePassword: 'password' } } } ``` -------------------------------- ### Optimize Pagination with Cursor-Based Queries Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/09-advanced-usage.md For large datasets, avoid inefficient skip/limit pagination. Instead, use range queries on sorted fields like '_id' to fetch subsequent pages efficiently. ```javascript // Instead of skip/limit (inefficient for large offsets) const page = await User.find({ status: 'active' }) .limit(20) .skip(1000); // Scans 1020 documents! // Use range queries on sorted fields const lastId = '507f1f77bcf86cd799439011'; const nextPage = await User.find({ status: 'active', _id: { '>': lastId } }).sort('_id ASC').limit(20); ``` -------------------------------- ### Configure Datastore URL via Environment Variable Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/07-configuration-reference.md Set the MongoDB connection URL using the MONGODB_URL environment variable, with a fallback to a local default. ```bash MONGODB_URL="mongodb+srv://user:pass@cluster.mongodb.net/db" NODE_ENV=production ``` ```javascript module.exports.datastores = { default: { adapter: 'sails-mongo', url: process.env.MONGODB_URL || 'mongodb://localhost:27017/mydb' } }; ``` -------------------------------- ### Create a new record using Waterline model Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/03-dml-methods.md This is the typical way to create a new record using a Waterline model. It abstracts away the low-level adapter details. ```javascript await User.create({ email: 'john@example.com', name: 'John' }); ``` -------------------------------- ### Create Product Indexes with Sails-Mongo Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/09-advanced-usage.md Define various types of indexes (single field, compound, text, TTL) on the 'products' collection for performance. Ensure the adapter is required and the database manager is accessible. ```javascript const adapter = require('sails-mongo'); const db = adapter.datastores['default'].manager.db(); async function createProductIndexes() { const products = db.collection('products'); // Single field indexes await products.createIndex({ sku: 1 }, { unique: true }); await products.createIndex({ category: 1 }); await products.createIndex({ price: 1 }); await products.createIndex({ createdAt: -1 }); // Compound indexes await products.createIndex({ category: 1, price: 1 }); await products.createIndex({ status: 1, createdAt: -1 }); // Text index for search await products.createIndex({ name: 'text', description: 'text' }); // TTL index (auto-delete after 30 days) await products.createIndex( { createdAt: 1 }, { expireAfterSeconds: 2592000 } ); console.log('Indexes created'); } createProductIndexes().catch(console.error); ``` -------------------------------- ### Handle Configuration Errors Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/08-types-and-errors.md Catch `E_BAD_CONFIG` errors when the datastore configuration is invalid, such as providing an incorrect URL format. ```javascript adapter.registerDatastore({ identity: 'default', url: 'invalid-url-format' }, {}, (err) => { if (err && err.code === 'E_BAD_CONFIG') { console.error('Invalid config:', err.message); } }); ``` -------------------------------- ### Configure Cluster/Replica Set Connection Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/06-connection-management.md Connect to MongoDB replica sets by specifying multiple host:port pairs in the URL and configuring replica set options like `replicaSet`, `readPreference`, `w`, and `j` for journaling. ```javascript { datastores: { default: { adapter: 'sails-mongo', url: 'mongodb://localhost:27017,localhost:27018,localhost:27019/mydb', replicaSet: 'rs0', readPreference: 'primary', w: 'majority', j: true // Journaling } } } ``` -------------------------------- ### MongoDB Connection URL Formats Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/07-configuration-reference.md Illustrates various formats for MongoDB connection URLs, including local, authenticated, replica set, MongoDB Atlas, and SSL configurations. ```javascript // Local MongoDB (no auth) 'mongodb://localhost:27017/mydb' ``` ```javascript // With credentials 'mongodb://user:password@localhost:27017/mydb' ``` ```javascript // Multiple hosts (replica set) 'mongodb://host1:27017,host2:27017,host3:27017/mydb?replicaSet=rs0' ``` ```javascript // MongoDB Atlas (cloud) 'mongodb+srv://user:password@cluster.mongodb.net/dbname' ``` ```javascript // With SSL 'mongodb://host:27017/mydb?ssl=true&tlsAllowInvalidCertificates=true' ``` -------------------------------- ### Allow Invalid SSL Certificates for Development Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/07-configuration-reference.md Configures the adapter to allow invalid SSL certificates and hostnames, suitable for development environments. Use with caution as it bypasses security checks. ```javascript { adapter: 'sails-mongo', url: 'mongodb://host:27017/db?ssl=true', tls: true, tlsAllowInvalidCertificates: true, // Dev only! tlsAllowInvalidHostnames: true // Dev only! } ``` -------------------------------- ### verifyModelDef Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/05-ddl-methods.md Verifies if a given model definition is compatible with the adapter's constraints. This method runs synchronously. ```APIDOC ## verifyModelDef ### Description Verifies if a given model definition is compatible with the adapter's constraints. This method runs synchronously. ### Method ```javascript adapter.verifyModelDef(modelDef).execSync() ``` ### Parameters #### Path Parameters - **modelDef** (Object) - Required - Model definition to validate ### Response Machine that switches to exits: - `success` — Model is compatible - `invalid` — Model has incompatible definition ### Example ```javascript try { const result = adapter.verifyModelDef({ identity: 'user', tableName: 'users', attributes: { id: { type: 'number', primaryKey: true }, email: { type: 'string', unique: true }, name: { type: 'string' } } }).execSync(); console.log('Model is valid'); } catch (e) { if (e.exit === 'invalid') { console.error('Model validation failed:', e.message); } else { throw e; } } ``` ``` -------------------------------- ### Verify Model Definition with verifyModelDef Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/05-ddl-methods.md Use `verifyModelDef` to check if a model definition is compatible with the adapter before registering it. This method runs synchronously and returns 'success' or 'invalid' exits. ```javascript try { const result = adapter.verifyModelDef({ identity: 'user', tableName: 'users', attributes: { id: { type: 'number', primaryKey: true }, email: { type: 'string', unique: true }, name: { type: 'string' } } }).execSync(); console.log('Model is valid'); } catch (e) { if (e.exit === 'invalid') { console.error('Model validation failed:', e.message); } else { throw e; } } ``` -------------------------------- ### Low-level Adapter Destroy Call Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/03-dml-methods.md Shows how to invoke the adapter's destroy method directly for deleting records. This method allows for more granular control, including fetching deleted records by setting `meta.fetch: true`. ```javascript // Low-level adapter call adapter.destroy('default', { using: 'users', criteria: { where: { email: 'spam@example.com' }, limit: 9007199254740991, skip: 0, sort: [] }, meta: { fetch: true } }, (err, deletedRecords) => { if (err) return console.error(err); console.log('Deleted:', deletedRecords.length, 'records'); }); ``` -------------------------------- ### Configure Sails Datastore Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/00-index.md Configure the default datastore in Sails to use the sails-mongo adapter with a MongoDB connection URL. ```javascript module.exports.datastores = { default: { adapter: 'sails-mongo', url: 'mongodb://localhost:27017/my_app' } }; ``` -------------------------------- ### Configure Multiple Datastores Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/07-configuration-reference.md Define multiple MongoDB datastore instances for different purposes within the application. This allows for segregation of data, such as primary databases, caches, and analytics stores. ```javascript module.exports.datastores = { default: { adapter: 'sails-mongo', url: 'mongodb://localhost:27017/primary_db' }, cache: { adapter: 'sails-mongo', url: 'mongodb://cache-server:27017/cache_db' }, analytics: { adapter: 'sails-mongo', url: 'mongodb://analytics-server:27017/analytics_db' } }; ``` ```javascript // Uses 'default' datastore module.exports = { /* ... */ }; // Or explicitly specify module.exports = { datastore: 'analytics', // ... }; ``` -------------------------------- ### Create MongoDB Connection Manager Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/02-lifecycle-methods.md Creates a MongoDB connection manager (client instance) using a connection string and optional meta options. Handles success, malformed, and failed connection attempts. ```javascript const adapter = require('sails-mongo'); adapter.createManager({ connectionString: 'mongodb://localhost:27017/mydb', meta: { ssl: true, poolSize: 20 } }).switch({ success: (report) => { const manager = report.manager; // Use MongoDB client }, malformed: (report) => { console.error('Invalid connection string:', report.error); }, failed: (report) => { console.error('Failed to connect:', report.error); } }); ``` -------------------------------- ### createManager Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/02-lifecycle-methods.md Creates a MongoDB connection manager (client instance) with the provided connection string and optional meta options. ```APIDOC ## createManager ### Description Create a MongoDB connection manager (client instance). ### Signature ```javascript createManager(connectionString, onUnexpectedFailure, meta) ``` ### Parameters #### Path Parameters - `connectionString` (String) - Required - MongoDB connection URL - `onUnexpectedFailure` (Function) - Optional - Callback for unexpected connection failures (unused in current version) - `meta` (Object) - Optional - Additional MongoDB client options (ssl, poolSize, etc.) ### Returns Machine that switches to exits: `success`, `malformed`, `failed`, `error` ### Example ```javascript const adapter = require('sails-mongo'); adapter.createManager({ connectionString: 'mongodb://localhost:27017/mydb', meta: { ssl: true, poolSize: 20 } }).switch({ success: (report) => { const manager = report.manager; // Use MongoDB client }, malformed: (report) => { console.error('Invalid connection string:', report.error); }, failed: (report) => { console.error('Failed to connect:', report.error); } }); ``` ``` -------------------------------- ### Handling Errors in Raw Adapter Calls Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/08-types-and-errors.md Shows how to handle errors returned from raw adapter calls using a callback function. It includes a switch statement for specific error codes like 'E_UNIQUE' and 'E_FAILED_TO_CONNECT', and a fallback for general network or unknown errors. ```javascript adapter.create('default', s3q, (err, result) => { if (err) { switch (err.code) { case 'E_UNIQUE': console.error('Unique constraint violated'); break; case 'E_FAILED_TO_CONNECT': console.error('Connection failed:', err.raw.message); break; default: if (err.name === 'MongoNetworkError') { console.error('Network error:', err.message); } else { console.error('Unknown error:', err); } } } }); ``` -------------------------------- ### Configure Sails-Mongo Migration Mode Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/07-configuration-reference.md Set the migration strategy for the default datastore. Use 'safe' in production to prevent accidental data loss. ```javascript module.exports.datastores = { default: { adapter: 'sails-mongo', url: 'mongodb://localhost:27017/mydb', migrate: 'safe' // 'create', 'alter', 'drop', or 'safe' } }; ``` -------------------------------- ### Create Operations Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/00-index.md Methods for creating records in the database. ```APIDOC ## Create Operations ### `adapter.create(datastoreName, s3q, callback)` Creates a single record. ### `adapter.createEach(datastoreName, s3q, callback)` Creates multiple records. ``` -------------------------------- ### Waterline to MongoDB Where Syntax Conversion Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/04-dql-methods.md Illustrates the conversion of Waterline query syntax to MongoDB query syntax for the `where` clause. ```javascript // Waterline syntax { status: 'active', age: { '>': 18 } } // Converted to MongoDB { status: 'active', age: { $gt: 18 } } ``` -------------------------------- ### Configuring MongoDB Timeouts Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/08-types-and-errors.md Provides configuration options for MongoDB connection and server selection timeouts. Adjust these values to manage responsiveness and prevent timeouts in slow or high-latency environments. ```javascript { connectTimeoutMS: 10000, socketTimeoutMS: 60000, serverSelectionTimeoutMS: 5000 } ``` -------------------------------- ### Environment-Specific Datastore Configuration Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/07-configuration-reference.md Override default datastore settings for different environments. The development configuration uses a local database, while production can use a remote URL. ```javascript module.exports.datastores = { default: { adapter: 'sails-mongo', url: 'mongodb://localhost:27017/my_app_dev' } }; ``` ```javascript module.exports.datastores = { default: { adapter: 'sails-mongo', url: process.env.MONGODB_URL, poolSize: 30, maxPoolSize: 60, retryWrites: true, w: 'majority', tls: true } }; ``` -------------------------------- ### Check Existing Indexes in Sails-Mongo Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/09-advanced-usage.md Retrieve and log all existing indexes for the 'products' collection. This requires the Sails-Mongo adapter to be initialized and accessible. ```javascript const adapter = require('sails-mongo'); const indexes = await adapter.datastores['default'] .manager.db() .collection('products') .getIndexes(); console.log('Existing indexes:'); indexes.forEach(idx => { console.log(' -', idx.name, idx.key); }); ``` -------------------------------- ### Configure Authentication with authSource Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/07-configuration-reference.md Resolves 'Authentication failed' errors by verifying credentials and specifying the 'authSource' parameter in the connection URL, particularly when using a user created in the 'admin' database. ```javascript // If using a user created in 'admin' database: url: 'mongodb://user:pass@host:27017/mydb?authSource=admin' ``` -------------------------------- ### Default Configuration Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/01-adapter-overview.md The default configuration settings for the sails-mongo adapter. ```APIDOC ## Default Configuration ```javascript { schema: false // Sails will not enforce the schema on the adapter side } ``` ``` -------------------------------- ### createEach Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/03-dml-methods.md Creates multiple new records in a single operation using the adapter's createEach method. This method is efficient as it leverages MongoDB's insertMany() operation. ```APIDOC ## createEach ### Description Creates multiple new records in a single operation. ### Method Signature ```javascript adapter.createEach(datastoreName, query, done) ``` ### Parameters #### Path Parameters - `datastoreName` (String) - Required - Identity of datastore to use #### Query Parameters - `query` (Object) - Required - Stage-3 query object - `using` (String) - Required - Collection name - `values` (Array) - Required - Array of objects to insert - `meta.fetch` (Boolean) - Optional - If `true`, return created records; if `false` (default), return undefined #### Request Body - `done` (Function) - Required - Callback `(err, createdRecords)` ### Response Calls `done(err)` on failure or `done(null, createdRecords)` on success. ### Behavior 1. Inserts multiple documents into the specified collection. 2. Uses MongoDB's `insertMany()` for efficiency. 3. If any record violates a unique constraint, the entire operation fails. 4. If `fetch: true`, returns all created records with `_id` populated. 5. If `fetch: false`, returns `undefined`. ### Example ```javascript // Low-level adapter call adapter.createEach('default', { using: 'users', values: [ { email: 'john@example.com', name: 'John' }, { email: 'jane@example.com', name: 'Jane' } ], meta: { fetch: true } }, (err, users) => { if (err) return console.error(err); console.log('Created:', users.length, 'records'); }); ``` ### Errors - `E_UNIQUE` — If any record violates a unique constraint (entire batch fails). - Standard MongoDB errors. ``` -------------------------------- ### Replica Set Cluster Configuration Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/07-configuration-reference.md Connect to a MongoDB replica set cluster, specifying read preferences and write concerns. ```javascript module.exports.datastores = { default: { adapter: 'sails-mongo', url: 'mongodb://host1:27017,host2:27017,host3:27017/mydb?replicaSet=rs0', replicaSet: 'rs0', w: 'majority', j: true, readPreference: 'primaryPreferred' } }; ``` -------------------------------- ### Safe Migration Pattern Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/05-ddl-methods.md Use `migrate: 'safe'` for production environments to prevent automatic schema migrations. Collections must pre-exist and match model definitions. ```javascript // config/migrations.js module.exports.datastores = { default: { migrate: 'safe' // Never auto-migrate (production mode) } }; ``` -------------------------------- ### Configure Sails-Mongo with Extended Options Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/02-lifecycle-methods.md Pass extended MongoDB client options via the datastore config or meta parameter. Supported options include SSL/TLS, connection pooling, timeouts, and authentication. ```javascript { datastores: { production: { adapter: 'sails-mongo', url: 'mongodb://localhost:27017/prod_db', ssl: true, sslValidate: true, sslCA: '/path/to/ca.pem', poolSize: 25, connectTimeoutMS: 5000, retryWrites: true, authMechanism: 'SCRAM-SHA-256' } } } ``` -------------------------------- ### registerDatastore Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/02-lifecycle-methods.md Registers a new datastore with the adapter. This method is called once per configured MongoDB datastore during Waterline initialization. ```APIDOC ## registerDatastore ### Description Registers a new datastore with the adapter. Called once per configured MongoDB datastore when Waterline initializes. ### Method Signature ```javascript registerDatastore(dsConfig, physicalModelsReport, done) ``` ### Parameters #### `dsConfig` (Object) - Required Datastore configuration object. - **`dsConfig.identity`** (String) - Required - Unique identifier for this datastore. - **`dsConfig.url`** (String) - Required - MongoDB connection URL (e.g., `mongodb://user:pass@localhost:27017/dbname`). - **`dsConfig.adapter`** (String) - Required - Should be `'sails-mongo'`. - **`dsConfig.schema`** (Boolean) - Optional - Set to `false` (default). Sails doesn't enforce schema on adapter side. #### `physicalModelsReport` (Object) - Required Map of model definitions keyed by table name. - **`physicalModelsReport[tableName].primaryKey`** (String) - Primary key attribute name. - **`physicalModelsReport[tableName].identity`** (String) - Model identity. - **`physicalModelsReport[tableName].tableName`** (String) - Collection name. - **`physicalModelsReport[tableName].definition`** (Object) - Attribute definitions from waterline-schema. #### `done` (Function) - Required Callback function. Calls `done(err)` on failure or `done(undefined, meta)` on success. ### Behavior 1. Validates datastore configuration. 2. Normalizes connection URL and options. 3. Validates all model definitions for adapter compatibility. 4. Creates a connection manager (MongoDB client instance). 5. Stores datastore entry in internal registry. 6. Tracks physical models for later queries. ### Example ```javascript const sails = require('sails'); sails.load({ datastores: { default: { adapter: 'sails-mongo', url: 'mongodb://localhost:27017/my_app', ssl: true, poolSize: 10 } } }, (err) => { if (err) return console.error(err); // Connection established }); ``` ### Errors - `E_BAD_CONFIG` — Invalid connection URL or configuration. - `E_FAILED_TO_CONNECT` — Cannot connect to MongoDB server. - `E_MODELS_NOT_COMPATIBLE` — One or more models incompatible with adapter. ``` -------------------------------- ### Configure MongoDB Connection Timeouts Source: https://github.com/balderdashy/sails-mongo/blob/master/_autodocs/06-connection-management.md Set various timeout behaviors for MongoDB connections, including establishment, socket (query), server selection, and connection pool idle times. ```javascript { datastores: { default: { adapter: 'sails-mongo', url: 'mongodb://localhost:27017/mydb', // Connection establishment timeout connectTimeoutMS: 10000, // Socket timeout (query timeout) socketTimeoutMS: 30000, // Server selection timeout serverSelectionTimeoutMS: 5000, // Connection pool idle timeout maxIdleTimeMS: 60000 } } } ```