### Find One Document in MarsDB Collection Source: https://context7.com/c58/marsdb/llms.txt Demonstrates retrieving a single document that matches the query criteria using `findOne()`. Supports finding by query, `_id`, and applying sorting to get the first matching document. ```javascript const users = new Collection('users'); // Find single document by query users.findOne({ email: 'alice@example.com' }) .then(user => { if (user) { console.log('Found user:', user.name); } else { console.log('User not found'); } }); // Find by _id users.findOne('user-id-123').then(user => { console.log('User by ID:', user); }); // findOne with sorting (returns first match) users.findOne({ role: 'admin' }) .sort({ createdAt: 1 }) .then(oldestAdmin => { console.log('First admin:', oldestAdmin); }); ``` -------------------------------- ### Collection Creation Source: https://context7.com/c58/marsdb/llms.txt Demonstrates how to create new collections, both persistent and in-memory, and set a default storage manager. ```APIDOC ## Collection Creation ### Description This section covers the initialization of MarsDB collections, including setting up storage managers and creating collections in different modes. ### Method `new Collection(name, options)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```javascript import Collection from 'marsdb'; import LocalForageManager from 'marsdb-localforage'; // Set default storage manager globally Collection.defaultStorageManager(LocalForageManager); // Create a persistent collection const users = new Collection('users'); // Create an in-memory collection const session = new Collection('session', { inMemory: true }); // Access collection properties console.log(users.modelName); // 'users' ``` ### Response #### Success Response (200) N/A (Constructor) #### Response Example N/A ``` -------------------------------- ### Create In-Memory Collection Source: https://github.com/c58/marsdb/blob/master/README.md Demonstrates creating a collection with a specific storage manager (e.g., LocalStorage) and also shows how to create an in-memory collection for session state. ```javascript import Collection from 'marsdb'; import LocalStorageManager from 'marsdb-localstorage'; // Set some defaults and create collection Collection.defaultStorageManager(LocalStorageManager); const users = new Collection('users'); // But it may be useful to create in-memory // collection without defined defaults // (for example to save some session state) const session = new Collection('session', {inMemory: true}); ``` -------------------------------- ### Create Collection with Default Storage Source: https://github.com/c58/marsdb/blob/master/README.md Sets up a default storage manager (e.g., LocalForage) and creates a new collection. All documents will be saved in the browser cache. ```javascript import Collection from 'marsdb'; import LocalForageManager from 'marsdb-localforage'; // Default storage is in-memory // Setup different storage managers // (all documents will be save in a browser cache) Collection.defaultStorageManager(LocalForageManager); // Create collection wit new default storage const users = new Collection('users'); ``` -------------------------------- ### Create MarsDB Collections Source: https://context7.com/c58/marsdb/llms.txt Demonstrates how to create new collections, set a default storage manager, and create both persistent and in-memory collections. Accesses collection properties like modelName, storage, and indexes. ```javascript import Collection from 'marsdb'; import LocalForageManager from 'marsdb-localforage'; // Set default storage manager globally (affects all new collections) Collection.defaultStorageManager(LocalForageManager); // Create a persistent collection const users = new Collection('users'); // Create an in-memory collection (ignores default storage) const session = new Collection('session', { inMemory: true }); // Access collection properties console.log(users.modelName); // 'users' console.log(users.storage); // StorageManager instance console.log(users.indexes); // IndexManager indexes ``` -------------------------------- ### Find with Pipeline Operations Source: https://github.com/c58/marsdb/blob/master/README.md Demonstrates chaining `limit`, `sortFunc`, `filter`, `map`, and `reduce` for complex data retrieval and transformation. The order of operations is crucial as each method acts on the result of the previous one. Use `aggregate` for single-document processing and `ifNotEmpty` to prevent further operations if no documents are found. ```javascript const posts = new Collection('posts'); // Get number of all comments in the DB posts.find() .limit(10) .sortFunc((a, b) => a - b + 10) .filter(doc => Matsh.sqrt(doc.comment.length) > 1.5) .map(doc => doc.comments.length) .reduce((acum, val) => acum + val) .then(result => { // result is a number of all comments // in all found posts }); // Result is `undefined` because posts // is not exists and additional processing // is not ran (thanks to `.ifNotEmpty()`) posts.find({author: 'not_existing_name'}) .aggregate(docs => docs[0]) .ifNotEmpty() .aggregate(user => user.name) ``` -------------------------------- ### Configure Storage Plugins Source: https://context7.com/c58/marsdb/llms.txt Set a global default storage manager or override it for specific collections. Collections can also be configured to be in-memory only. Storage operations like loading, reloading, and destroying data are accessible via the `storage` property. ```javascript import Collection from 'marsdb'; import LocalForageManager from 'marsdb-localforage'; import LocalStorageManager from 'marsdb-localstorage'; // Set global default storage Collection.defaultStorageManager(LocalForageManager); // All new collections use LocalForage const users = new Collection('users'); const posts = new Collection('posts'); // Override for specific collection const cache = new Collection('cache', { storageManager: LocalStorageManager }); // In-memory only (no persistence) const session = new Collection('session', { inMemory: true }); // Access storage directly users.storage.loaded().then(() => { console.log('Storage loaded and ready'); }); // Reload from storage users.storage.reload().then(() => { console.log('Storage reloaded'); }); // Destroy all stored data users.storage.destroy().then(() => { console.log('Storage cleared'); }); ``` -------------------------------- ### Basic Observation of Query Results Source: https://context7.com/c58/marsdb/llms.txt Observe query results and react to changes in real-time using the `observe` method. The callback is invoked on initial results and every subsequent change. ```javascript const messages = new Collection('messages'); // Start observing - callback invoked on initial result and every change const stopper = messages.find({ roomId: 'general' }) .sort({ createdAt: -1 }) .limit(50) .observe(docs => { console.log('Messages updated:', docs.length); renderMessages(docs); }); // The observe() returns a Promise with stop() method stopper.then(initialDocs => { console.log('Initial messages loaded:', initialDocs.length); }); // Stop observing when done document.getElementById('leaveRoom').onclick = () => { stopper.stop(); console.log('Stopped observing messages'); }; ``` -------------------------------- ### Reactive Joins with Observe Source: https://context7.com/c58/marsdb/llms.txt Create joins that automatically update when related data changes by using `observe` instead of `then`. This is useful for real-time UIs. ```javascript const users = new Collection('users'); const posts = new Collection('posts'); // Reactive join - updates when user document changes const stopper = posts.find({ featured: true }) .join(doc => { // Use observe instead of then for reactive join return users.findOne(doc.authorId).observe(user => { doc.author = user; }); }) .observe(posts => { // Called whenever posts OR joined users change console.log('Updated posts with authors:', posts); renderPosts(posts); }); // Later: stop observing // stopper.stop(); // Manual update propagation in joins posts.find() .join((doc, updated) => { doc.cachedData = getCachedData(doc._id); // Manually trigger update later onCacheInvalidate(doc._id, () => { doc.cachedData = getCachedData(doc._id); updated(); // Propagates update to observers }); }) .observe(posts => { console.log('Posts updated:', posts); }); ``` -------------------------------- ### Create Seeded Random Generator Source: https://context7.com/c58/marsdb/llms.txt Use `createWithSeeds` to generate deterministic random sequences for testing. The same seeds will always produce the same sequence of random IDs and fractions. ```javascript import { Random } from 'marsdb'; // Create seeded generator (reproducible) const seeded = Random.createWithSeeds('my-seed', 42, 'test'); // Same seeds always produce same sequence console.log(seeded.id()); // Always same value with these seeds console.log(seeded.fraction()); // Reproducible // Useful for testing const testRandom = Random.createWithSeeds('test-seed'); const testId1 = testRandom.id(); const testId2 = testRandom.id(); const testRandom2 = Random.createWithSeeds('test-seed'); console.log(testRandom2.id() === testId1); // true console.log(testRandom2.id() === testId2); // true ``` -------------------------------- ### Join Related Documents Source: https://github.com/c58/marsdb/blob/master/README.md Demonstrates joining documents from different collections. You can use promises for asynchronous joins or `observe` for reactive joins. The `join` method can also accept a specification object for faster joining, performing a single find for all posts. The `updated` callback allows manual propagation of update events. ```javascript const users = new Collection('users'); const posts = new Collection('posts'); posts.find() .join(doc => { // Return a Promise for waiting of the result. return users.findOne(doc.authorId).then(user => { doc.authorObj = user; // any return is ignored }); }) .join(doc => { // For reactive join you must invoke `observe` instead `then` // That's it! return users.findOne(doc.authorId).observe(user => { doc.authorObj = user; }); }) .join((doc, updated) => { // Also any other “join” mutations supported doc.another = _cached_data_by_post[doc._id]; // Manually update a joined parameter and propagate // update event from current cursor to a root // (`observe` callback invoked) setTimeout(() => { doc.another = 'some another user'; updated(); }, 10); }) // Or just pass join spec object for fast joining // (only one `find` will be produced for all posts) .join({ authorId: users }) // posts[i].authorId will be user object .observe((posts) => { // do something with posts with authors // invoked any time when posts changed // (and when observed joins changed too) }) ``` -------------------------------- ### Basic Joins with Function Source: https://context7.com/c58/marsdb/llms.txt Join related documents from different collections by providing a function to the `join` method. This function should return a Promise that resolves when the join operation is complete. ```javascript const users = new Collection('users'); const posts = new Collection('posts'); // Join with function - load author for each post posts.find() .join(doc => { return users.findOne(doc.authorId).then(user => { doc.author = user; }); }) .then(postsWithAuthors => { postsWithAuthors.forEach(post => { console.log(`${post.title} by ${post.author.name}`); }); }); // Multiple joins const comments = new Collection('comments'); posts.find() .join(doc => { return users.findOne(doc.authorId).then(user => { doc.author = user; }); }) .join(doc => { return comments.find({ postId: doc._id }).then(postComments => { doc.comments = postComments; }); }) .then(posts => { console.log('Posts with authors and comments:', posts); }); ``` -------------------------------- ### Finding Documents Source: https://context7.com/c58/marsdb/llms.txt Explains how to query collections using MongoDB-style selectors, including chaining methods for projection, sorting, skipping, and limiting. ```APIDOC ## Finding Documents ### Description This section covers querying documents within a collection using flexible, MongoDB-compatible selectors. The `find()` method returns a cursor that allows for chaining operations like projection, sorting, and pagination. ### Method `find(selector)` `find(selector).project(fields)` `find(selector).sort(sortSpecifier)` `find(selector).skip(number)` `find(selector).limit(number)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **selector** (Object) - Optional - MongoDB-style query object. - **fields** (Object) - Optional - Projection object specifying fields to include/exclude. - **sortSpecifier** (Object | Array) - Optional - Sort order specification. - **number** (Number) - Optional - Number of documents to skip or limit. ### Request Example ```javascript const posts = new Collection('posts'); // Find all documents posts.find().then(docs => { console.log('All posts:', docs); }); // Find with query selector posts.find({ author: 'Alice' }).then(docs => { console.log('Posts by Alice:', docs); }); // Find with comparison operators posts.find({ views: { $gt: 100 }, tags: { $in: ['javascript', 'database'] } }).then(docs => { console.log('Popular JS/DB posts:', docs); }); // Find with projection posts.find({ author: 'Bob' }) .project({ title: 1, createdAt: 1 }) .then(docs => { console.log('Projected docs:', docs); }); // Find with sorting posts.find() .sort({ createdAt: -1 }) // Descending by date .then(docs => { console.log('Latest posts first:', docs); }); // Find with skip and limit (pagination) posts.find() .sort({ createdAt: -1 }) .skip(10) .limit(5) .then(docs => { console.log('Page 3 (5 per page):', docs); }); ``` ### Response #### Success Response (200) - **docs** (Array) - An array of documents matching the query. #### Response Example ```json { "example": "All posts: [ { _id: '...', title: '...', ... }, ... ]" } ``` ```json { "example": "Projected docs: [ { _id: '...', title: '...', createdAt: Date }, ... ]" } ``` ``` -------------------------------- ### Inserting Documents Source: https://context7.com/c58/marsdb/llms.txt Shows how to insert single or multiple documents into a collection, with or without custom IDs. ```APIDOC ## Inserting Documents ### Description This section details how to add new documents to a MarsDB collection. Documents can be inserted individually or in batches, and `_id` fields can be auto-generated or provided manually. ### Method `insert(document)` `insertAll(...documents)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **document** (Object) - Required - The document to insert. - **...documents** (Object) - Required - Multiple documents to insert. ### Request Example ```javascript const posts = new Collection('posts'); // Insert single document posts.insert({ title: 'Getting Started with MarsDB', author: 'Alice', tags: ['database', 'javascript'], createdAt: new Date() }).then(docId => { console.log('Inserted document with ID:', docId); }); // Insert with custom _id posts.insert({ _id: 'custom-id-123', title: 'Custom ID Document', author: 'Bob' }).then(docId => { console.log('Inserted with custom ID:', docId); }); // Insert multiple documents at once posts.insertAll( { title: 'First Post', author: 'Alice' }, { title: 'Second Post', author: 'Bob' }, { title: 'Third Post', author: 'Charlie' } ).then(docIds => { console.log('Inserted documents:', docIds); }); ``` ### Response #### Success Response (200) - **docId** (String) - The `_id` of the inserted document. - **docIds** (Array) - An array of `_id`s for the inserted documents. #### Response Example ```json { "example": "Inserted document with ID: 4kJhF9TmPwRa3Yn2Q" } ``` ```json { "example": "Inserted documents: ['abc123', 'def456', 'ghi789']" } ``` ``` -------------------------------- ### Object Specification Joins Source: https://context7.com/c58/marsdb/llms.txt Use object syntax for simple joins, which performs a single optimized query. This replaces the specified field with the joined document. ```javascript const users = new Collection('users'); const posts = new Collection('posts'); const categories = new Collection('categories'); // Simple object join - replaces field with joined document posts.find() .join({ authorId: users }) .then(posts => { // posts[i].authorId is now the full user object console.log('Author:', posts[0].authorId.name); }); // Multiple field joins posts.find() .join({ authorId: users, categoryId: categories }) .then(posts => { posts.forEach(post => { console.log(`${post.title} in ${post.categoryId.name} by ${post.authorId.name}`); }); }); ``` -------------------------------- ### Find Documents with Projection and Sorting Source: https://github.com/c58/marsdb/blob/master/README.md Finds documents in a collection, projects specific fields, sorts the results, and handles the promise with a callback. ```javascript const posts = new Collection('posts'); posts.find({author: 'Bob'}) .project({author: 1}) .sort(['createdAt']) .then(docs => { // do something with docs }); ``` -------------------------------- ### Pipeline: Map Documents to Summaries Source: https://context7.com/c58/marsdb/llms.txt Transform each document in a query result into a new format using the .map() pipeline operation. This is useful for creating summary views or extracting specific data points. ```javascript const orders = new Collection('orders'); // Map - Transform each document orders.find({ status: 'completed' }) .map(order => ({ id: order._id, total: order.items.reduce((sum, item) => sum + item.price, 0), itemCount: order.items.length })) .then(summaries => { console.log('Order summaries:', summaries); }); ``` -------------------------------- ### Insert Multiple Documents Source: https://github.com/c58/marsdb/blob/master/README.md Inserts multiple documents into a collection using `insertAll`. The `then` callback is invoked once all documents have been inserted. ```javascript const posts = new Collection('posts'); posts.insertAll( {text: 'MarsDB'}, {text: 'is'}, {text: 'awesome'} ).then(docsIds => { // invoked when all documents inserted }); ``` -------------------------------- ### Listen to Collection Events Source: https://context7.com/c58/marsdb/llms.txt Subscribe to 'insert', 'update', and 'remove' events on a collection to trigger custom logic. 'beforeInsert' and 'beforeUpdate' hooks can be used for validation or data transformation before operations are applied. ```javascript const posts = new Collection('posts'); // Listen to insert events posts.on('insert', (newDoc, originalDoc, randomId) => { console.log('Document inserted:', newDoc._id); indexForSearch(newDoc); }); // Listen to update events posts.on('update', (updatedDoc, originalDoc) => { console.log('Document updated:', updatedDoc._id); console.log('Changed from:', originalDoc); console.log('Changed to:', updatedDoc); }); // Listen to remove events posts.on('remove', (newDoc, removedDoc) => { console.log('Document removed:', removedDoc._id); removeFromSearchIndex(removedDoc._id); }); // Before hooks (for validation/transformation) posts.on('beforeInsert', (doc, randomId) => { doc.createdAt = new Date(); doc.updatedAt = new Date(); }); posts.on('beforeUpdate', (query, modifier, options) => { modifier.$set = modifier.$set || {}; modifier.$set.updatedAt = new Date(); }); // Sync events (for replication) posts.on('sync:insert', (doc, randomId) => { sendToServer('insert', doc); }); posts.on('sync:update', (query, modifier, options) => { sendToServer('update', { query, modifier, options }); }); ``` -------------------------------- ### Insert Documents into MarsDB Collection Source: https://context7.com/c58/marsdb/llms.txt Shows how to insert single or multiple documents into a MarsDB collection. Documents automatically receive an `_id` if not provided, or you can specify a custom `_id`. ```javascript const posts = new Collection('posts'); // Insert single document posts.insert({ title: 'Getting Started with MarsDB', author: 'Alice', tags: ['database', 'javascript'], createdAt: new Date() }).then(docId => { console.log('Inserted document with ID:', docId); // Output: Inserted document with ID: 4kJhF9TmPwRa3Yn2Q }); // Insert with custom _id posts.insert({ _id: 'custom-id-123', title: 'Custom ID Document', author: 'Bob' }).then(docId => { console.log('Inserted with custom ID:', docId); // Output: Inserted with custom ID: custom-id-123 }); // Insert multiple documents at once posts.insertAll( { title: 'First Post', author: 'Alice' }, { title: 'Second Post', author: 'Bob' }, { title: 'Third Post', author: 'Charlie' } ).then(docIds => { console.log('Inserted documents:', docIds); // Output: Inserted documents: ['abc123', 'def456', 'ghi789'] }); ``` -------------------------------- ### Pipeline: Custom Sort Function Source: https://context7.com/c58/marsdb/llms.txt Implement custom sorting logic using .sortFunc() when standard field-based sorting is insufficient. Provide a comparison function that defines the desired order. ```javascript const products = new Collection('products'); // Custom sort function products.find({ inStock: true }) .sortFunc((a, b) => { // Sort by rating descending, then by price ascending if (b.rating !== a.rating) { return b.rating - a.rating; } return a.price - b.price; }) .then(sorted => { console.log('Best value products:', sorted); }); ``` ```javascript products.find() .sortFunc((a, b) => { // Featured items first, then by date if (a.featured && !b.featured) return -1; if (!a.featured && b.featured) return 1; return new Date(b.createdAt) - new Date(a.createdAt); }) .then(docs => console.log('Featured first:', docs)); ``` -------------------------------- ### Observe Collection Changes Source: https://github.com/c58/marsdb/blob/master/README.md Uses the `observe` method on a find cursor to receive real-time updates. Updates are batched and debounced by default. The `stopper` object can be used to stop observing, and the `then` callback is invoked once after the initial result. ```javascript const posts = new Collection('posts'); const stopper = posts.find({tags: {$in: ['marsdb', 'is', 'awesome']}}) .observe(docs => { // invoked on every result change // (on initial result too) stopper.stop(); // stops observing }).then(docs => { // invoked once on initial result // (after `observer` callback) }); ``` -------------------------------- ### Finding One Document Source: https://context7.com/c58/marsdb/llms.txt Details on how to retrieve a single document that matches the specified query criteria. ```APIDOC ## Finding One Document ### Description Use the `findOne()` method to retrieve a single document that matches the provided query. This is useful for fetching specific records or when only one result is expected. ### Method `findOne(query)` `findOne(query).sort(sortSpecifier)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **query** (Object | String) - Required - The query selector or the `_id` of the document to find. - **sortSpecifier** (Object | Array) - Optional - Sort order specification (applied before finding the first match). ### Request Example ```javascript const users = new Collection('users'); // Find single document by query users.findOne({ email: 'alice@example.com' }) .then(user => { if (user) { console.log('Found user:', user.name); } else { console.log('User not found'); } }); // Find by _id users.findOne('user-id-123').then(user => { console.log('User by ID:', user); }); // findOne with sorting (returns first match) users.findOne({ role: 'admin' }) .sort({ createdAt: 1 }) .then(oldestAdmin => { console.log('First admin:', oldestAdmin); }); ``` ### Response #### Success Response (200) - **user** (Object | null) - The found document, or null if no match is found. #### Response Example ```json { "example": "Found user: Alice" } ``` ```json { "example": "User by ID: null" } ``` ``` -------------------------------- ### Pipeline: Custom Aggregate Function Source: https://context7.com/c58/marsdb/llms.txt Perform custom aggregation on the entire result set using the .aggregate() pipeline operation. Pass a function that receives all documents and returns the aggregated result. ```javascript const posts = new Collection('posts'); // Get first document posts.find({ author: 'Alice' }) .aggregate(docs => docs[0]) .then(firstPost => { console.log('First post by Alice:', firstPost); }); ``` ```javascript posts.find() .aggregate(docs => { return docs.reduce((groups, doc) => { const category = doc.category || 'uncategorized'; groups[category] = groups[category] || []; groups[category].push(doc); return groups; }, {}); }) .then(grouped => { console.log('Posts by category:', grouped); }); ``` ```javascript posts.find({ published: true }) .aggregate(docs => ({ count: docs.length, totalViews: docs.reduce((sum, d) => sum + (d.views || 0), 0), avgViews: docs.length > 0 ? docs.reduce((sum, d) => sum + (d.views || 0), 0) / docs.length : 0 })) .then(stats => { console.log('Post statistics:', stats); }); ``` -------------------------------- ### EJSON Deep Cloning and Comparison Source: https://context7.com/c58/marsdb/llms.txt Perform deep cloning of objects to create independent copies. Compare objects for deep equality, with an option for key-order-sensitive comparison. ```javascript import { EJSON } from 'marsdb'; // Deep clone const original = { nested: { array: [1, 2, { deep: true }] }, date: new Date() }; const cloned = EJSON.clone(original); cloned.nested.array.push(4); console.log(original.nested.array.length); // 3 (unchanged) console.log(cloned.nested.array.length); // 4 // Deep equality comparison const a = { date: new Date('2024-01-01'), tags: ['a', 'b'] }; const b = { date: new Date('2024-01-01'), tags: ['a', 'b'] }; const c = { date: new Date('2024-01-02'), tags: ['a', 'b'] }; console.log(EJSON.equals(a, b)); // true console.log(EJSON.equals(a, c)); // false // Key order sensitive comparison const x = { a: 1, b: 2 }; const y = { b: 2, a: 1 }; console.log(EJSON.equals(x, y)); // true console.log(EJSON.equals(x, y, { keyOrderSensitive: true })); // false ``` -------------------------------- ### Generate Random IDs and Secrets Source: https://context7.com/c58/marsdb/llms.txt Generate various types of random data using the `Random` utility. Includes document IDs, short IDs, secret tokens, hex strings, random fractions, and random choices from arrays. ```javascript import { Random } from 'marsdb'; // Get default random generator (auto-detects best source) const random = Random.default(); // Generate document ID (17 chars, ~96 bits entropy) const id = random.id(); console.log(id); // e.g., 'KjW8nPq2XYFT4mH3a' // Custom length ID const shortId = random.id(8); console.log(shortId); // e.g., 'Pm3Kx7Wr' // Generate secret token (43 chars, ~256 bits entropy) const token = random.secret(); console.log(token); // e.g., 'a8Kp2mXw...' (43 chars) // Hex string const hex = random.hexString(16); console.log(hex); // e.g., '3f8a2b1c9d4e5f6a' // Random fraction (0-1) const fraction = random.fraction(); console.log(fraction); // e.g., 0.7234521 // Random choice from array/string const colors = ['red', 'green', 'blue']; const color = random.choice(colors); console.log(color); // e.g., 'green' ``` -------------------------------- ### Debounce and Batch Updates for Collections Source: https://context7.com/c58/marsdb/llms.txt Control update frequency for performance. Use debounce to limit updates within a time window and batchSize to force updates after a certain number of changes. ```javascript const events = new Collection('events'); // Customize debounce timing (default: ~16ms / 60fps) events.find({ type: 'click' }) .debounce(100) // Wait 100ms between updates .observe(docs => { console.log('Click events:', docs.length); }); // Batch size - force update after N changes even within debounce events.find({ type: 'mousemove' }) .debounce(500) .batchSize(50) // Update after 50 changes even if 500ms hasn't passed .observe(docs => { console.log('Mouse events:', docs.length); }); // Set global defaults import { CursorObservable } from 'marsdb'; CursorObservable.defaultDebounce(1000 / 30); // 30fps CursorObservable.defaultBatchSize(20); ``` -------------------------------- ### Conditionally Continue Pipeline with ifNotEmpty Source: https://context7.com/c58/marsdb/llms.txt Use `ifNotEmpty` to ensure subsequent operations only execute if the pipeline has results. This prevents errors on empty collections or intermediate empty results. ```javascript const users = new Collection('users'); // Safely chain operations on potentially empty results users.find({ username: 'nonexistent' }) .aggregate(docs => docs[0]) .ifNotEmpty() .aggregate(user => user.profile) .ifNotEmpty() .aggregate(profile => profile.avatar) .then(avatar => { // avatar is undefined if user doesn't exist // (pipeline stopped at ifNotEmpty) console.log('Avatar:', avatar || 'No avatar found'); }); // Prevent errors on empty arrays const posts = new Collection('posts'); posts.find({ author: 'unknown-author' }) .ifNotEmpty() .map(post => post.title.toUpperCase()) // Won't throw if empty .then(titles => { console.log('Titles:', titles); // [] }); ``` -------------------------------- ### Query Array for All Elements with $all Source: https://context7.com/c58/marsdb/llms.txt Use the $all operator to match documents where an array field contains all the specified elements. Ensure all listed values are present in the array. ```javascript posts.find({ tags: { $all: ['javascript', 'tutorial'] } }).then(docs => console.log('JS tutorial posts:', docs)); ``` -------------------------------- ### Query Strings with Direct Regular Expressions Source: https://context7.com/c58/marsdb/llms.txt Perform case-insensitive searches or prefix matches directly using JavaScript regular expressions. Ensure the field is a string type for regex operations. ```javascript const products = new Collection('products'); // Direct regex products.find({ name: /^iPhone/i // Case-insensitive, starts with 'iPhone' }).then(docs => console.log('iPhone products:', docs)); ``` -------------------------------- ### Query Documents with Comparison Operators Source: https://context7.com/c58/marsdb/llms.txt Use standard MongoDB comparison operators like $eq, $gt, $lt, $in, $nin, and $exists for precise document querying. ```javascript const products = new Collection('products'); // $eq - Equal (implicit) products.find({ price: 100 }).then(docs => console.log(docs)); ``` ```javascript // $gt, $gte, $lt, $lte - Greater/Less than products.find({ price: { $gte: 50, $lt: 200 } }).then(docs => { console.log('Products between $50-$200:', docs); }); ``` ```javascript // $ne - Not equal products.find({ status: { $ne: 'discontinued' } }) .then(docs => console.log('Active products:', docs)); ``` ```javascript // $in - Match any value in array products.find({ category: { $in: ['electronics', 'computers', 'phones'] } }).then(docs => console.log('Tech products:', docs)); ``` ```javascript // $nin - Not in array products.find({ brand: { $nin: ['BrandX', 'BrandY'] } }).then(docs => console.log('Other brands:', docs)); ``` ```javascript // $exists - Field existence products.find({ discount: { $exists: true } }) .then(docs => console.log('Discounted products:', docs)); ``` ```javascript // $type - Match BSON type products.find({ metadata: { $type: 3 } }) // 3 = Object .then(docs => console.log('Has metadata object:', docs)); ``` -------------------------------- ### Find Documents in MarsDB Collection Source: https://context7.com/c58/marsdb/llms.txt Illustrates querying documents using MongoDB-style selectors. Supports chaining operations like projection, sorting, skip, and limit for pagination. ```javascript const posts = new Collection('posts'); // Find all documents posts.find().then(docs => { console.log('All posts:', docs); }); // Find with query selector posts.find({ author: 'Alice' }).then(docs => { console.log('Posts by Alice:', docs); }); // Find with comparison operators posts.find({ views: { $gt: 100 }, tags: { $in: ['javascript', 'database'] } }).then(docs => { console.log('Popular JS/DB posts:', docs); }); // Find with projection (select specific fields) posts.find({ author: 'Bob' }) .project({ title: 1, createdAt: 1 }) .then(docs => { console.log('Projected docs:', docs); // Output: [{ _id: '...', title: '...', createdAt: Date }] }); // Find with sorting posts.find() .sort({ createdAt: -1 }) // Descending by date .then(docs => { console.log('Latest posts first:', docs); }); // Find with array sort specification posts.find() .sort(['author', ['createdAt', 'desc']]) .then(docs => { console.log('Sorted posts:', docs); }); // Find with skip and limit (pagination) posts.find() .sort({ createdAt: -1 }) .skip(10) .limit(5) .then(docs => { console.log('Page 3 (5 per page):', docs); }); ``` -------------------------------- ### Pipeline: Chained Operations Source: https://context7.com/c58/marsdb/llms.txt Combine multiple pipeline operations (.limit(), .filter(), .map(), .reduce()) sequentially to perform complex data transformations and aggregations. Operations are executed in the order they are chained. ```javascript orders.find() .limit(100) .filter(order => order.status === 'completed') .map(order => order.items.length) .reduce((sum, count) => sum + count, 0) .then(totalItems => { console.log('Total items in last 100 completed orders:', totalItems); }); ``` -------------------------------- ### Query Documents with Logical Operators Source: https://context7.com/c58/marsdb/llms.txt Combine multiple query conditions using logical operators such as $and, $or, $nor, and $not for complex filtering. ```javascript const users = new Collection('users'); // $and - All conditions must match users.find({ $and: [ { age: { $gte: 18 } }, { verified: true }, { role: 'member' } ] }).then(docs => console.log('Verified adult members:', docs)); ``` ```javascript // $or - At least one condition matches users.find({ $or: [ { role: 'admin' }, { role: 'moderator' } ] }).then(docs => console.log('Staff users:', docs)); ``` ```javascript // $nor - None of the conditions match users.find({ $nor: [ { banned: true }, { suspended: true } ] }).then(docs => console.log('Active users:', docs)); ``` ```javascript // $not - Negate a condition users.find({ age: { $not: { $lt: 18 } } }).then(docs => console.log('Adult users:', docs)); ``` ```javascript // Combined logical operators users.find({ $and: [ { $or: [{ role: 'admin' }, { permissions: 'write' }] }, { active: true } ] }).then(docs => console.log('Active users with write access:', docs)); ``` -------------------------------- ### Update Documents Source: https://github.com/c58/marsdb/blob/master/README.md Updates documents matching a query. The `then` callback provides results including the count of modified documents, an array of updated documents, and an array of original documents. The `upsert` option can be used to insert a document if no matches are found. ```javascript const posts = new Collection('posts'); posts.update( {authorId: {$in: [1, 2, 3]}}, {$set: {text: 'noop'}} ).then(result => { console.log(result.modified) // count of modified docs console.log(result.updated) // array of updated docs console.log(result.original) // array of original docs }); // Upsert (insert when nothing found) posts.update( {authorId: "123"}, {$set: {text: 'noop'}}, {upsert: true} ).then(result => { // { authorId: "123", text: 'noop', _id: '...' } }); ``` -------------------------------- ### Query Array by Size with $size Source: https://context7.com/c58/marsdb/llms.txt Use the $size operator to find documents where an array field has an exact number of elements. This is useful for enforcing specific array lengths. ```javascript posts.find({ tags: { $size: 3 } }).then(docs => console.log('Posts with exactly 3 tags:', docs)); ``` -------------------------------- ### Count Documents Source: https://context7.com/c58/marsdb/llms.txt Efficiently count documents matching a query using indexes. Supports counting all documents or documents matching specific criteria. ```javascript const posts = new Collection('posts'); // Count all documents posts.count().then(count => { console.log('Total posts:', count); }); ``` ```javascript // Count with query posts.count({ author: 'Alice', published: true }).then(count => { console.log('Published posts by Alice:', count); }); ``` -------------------------------- ### Query Array Elements with $elemMatch Source: https://context7.com/c58/marsdb/llms.txt Use $elemMatch to find documents where at least one array element matches multiple conditions. This is useful for complex criteria on array contents. ```javascript const posts = new Collection('posts'); // $elemMatch - Match array element with multiple conditions posts.find({ comments: { $elemMatch: { author: 'Alice', likes: { $gt: 10 } } } }).then(docs => console.log('Posts with popular Alice comments:', docs)); ``` -------------------------------- ### EJSON Serialization and Parsing Source: https://context7.com/c58/marsdb/llms.txt Serialize JavaScript objects to EJSON strings, preserving complex types like Dates and binary data. Parse EJSON strings back into objects, restoring original types. ```javascript import { EJSON } from 'marsdb'; // Serialize to JSON string (preserves Date, binary, etc.) const doc = { name: 'Test', createdAt: new Date(), data: new Uint8Array([1, 2, 3, 4]) }; const jsonString = EJSON.stringify(doc); console.log(jsonString); // Output: {"name":"Test","createdAt":{"$date":1234567890},"data":{"$binary":"AQIDBA=="}} // Parse back to object (restores types) const parsed = EJSON.parse(jsonString); console.log(parsed.createdAt instanceof Date); // true console.log(parsed.data instanceof Uint8Array); // true ``` -------------------------------- ### Geospatial Query with GeoJSON and $near Source: https://context7.com/c58/marsdb/llms.txt Query for documents near a GeoJSON point using the $near operator with a $geometry object. Specify distance in meters and ensure the 'location' field is indexed with a 2dsphere index. ```javascript locations.find({ location: { $near: { $geometry: { type: 'Point', coordinates: [-74.0060, 40.7128] // [lng, lat] }, $maxDistance: 10000 // meters } } }).then(docs => { console.log('GeoJSON nearby:', docs); }); ``` -------------------------------- ### Remove Documents Source: https://github.com/c58/marsdb/blob/master/README.md Removes documents matching a query. The `then` callback is invoked with an array of the removed documents. ```javascript const posts = new Collection('posts'); posts.remove({authorId: {$in: [1,2,3]}}) .then(removedDocs => { // do something with removed documents array }); ``` -------------------------------- ### Pipeline: Reduce Results to a Single Value Source: https://context7.com/c58/marsdb/llms.txt Aggregate query results into a single value using the .reduce() pipeline operation. This is commonly used for calculations like sums, averages, or counts across a dataset. ```javascript orders.find({ status: 'completed' }) .map(order => order.total) .reduce((sum, total) => sum + total, 0) .then(totalRevenue => { console.log('Total revenue:', totalRevenue); }); ``` -------------------------------- ### Insert Single Document Source: https://github.com/c58/marsdb/blob/master/README.md Inserts a single document into a collection. The `then` callback is invoked after the document has been persisted. ```javascript const posts = new Collection('posts'); posts.insert({text: 'MarsDB is awesome'}).then(docId => { // Invoked after persisting document }) ``` -------------------------------- ### Pipeline: Filter Documents Client-Side Source: https://context7.com/c58/marsdb/llms.txt Apply additional filtering to query results after they have been retrieved using the .filter() pipeline operation. This is useful for criteria that cannot be expressed in the initial query. ```javascript orders.find({ status: 'completed' }) .filter(order => order.total > 100) .then(largeOrders => { console.log('Large orders:', largeOrders); }); ``` -------------------------------- ### Geospatial Query with $near and Distance Source: https://context7.com/c58/marsdb/llms.txt Find documents within a specified radius of a given coordinate pair using the $near operator and $maxDistance. Ensure the 'coordinates' field is indexed for geospatial queries. ```javascript const locations = new Collection('locations'); // $near - Find nearby coordinate pairs locations.find({ coordinates: { $near: [40.7128, -74.0060], // NYC coordinates $maxDistance: 0.1 // Within ~11km } }).then(docs => { console.log('Nearby locations:', docs); }); ``` -------------------------------- ### Query Strings with $regex Operator Source: https://context7.com/c58/marsdb/llms.txt Use the $regex operator for more control over regular expression matching, including case sensitivity options. This is suitable for complex pattern matching on string fields. ```javascript products.find({ description: { $regex: 'premium', $options: 'i' } }).then(docs => console.log('Premium products:', docs)); ``` ```javascript products.find({ sku: { $regex: '^[A-Z]{3}-[0-9]{4}$' } }).then(docs => console.log('Valid SKU format:', docs)); ``` -------------------------------- ### EJSON Custom Type Registration Source: https://context7.com/c58/marsdb/llms.txt Register custom types for EJSON serialization and deserialization. Define a type with `typeName` and `toJSONValue` methods, then add a factory for deserialization. ```javascript import { EJSON } from 'marsdb'; // Define custom type class Money { constructor(amount, currency) { this.amount = amount; this.currency = currency; } typeName() { return 'Money'; } toJSONValue() { return { amount: this.amount, currency: this.currency }; } } // Register factory for deserialization EJSON.addType('Money', (json) => { return new Money(json.amount, json.currency); }); // Use in documents const order = { item: 'Widget', price: new Money(29.99, 'USD') }; const serialized = EJSON.stringify(order); const restored = EJSON.parse(serialized); console.log(restored.price instanceof Money); // true console.log(restored.price.currency); // 'USD' ``` -------------------------------- ### Remove Documents Source: https://context7.com/c58/marsdb/llms.txt Remove documents from a collection by specifying a query selector. Supports removing single, multiple, or all documents. ```javascript const posts = new Collection('posts'); // Remove single document posts.remove({ _id: 'post-123' }).then(removedDocs => { console.log('Removed:', removedDocs.length, 'document(s)'); }); ``` ```javascript // Remove multiple documents posts.remove({ author: 'spam-user', status: 'draft' }) .then(removedDocs => { console.log('Removed spam drafts:', removedDocs); }); ``` ```javascript // Remove all documents (be careful!) posts.remove({}).then(removedDocs => { console.log('Cleared collection, removed:', removedDocs.length); }); ``` -------------------------------- ### Stop Collection Observers Source: https://context7.com/c58/marsdb/llms.txt Properly clean up observers to prevent memory leaks. Observers can be stopped individually using a stopper object or all at once for a specific cursor. ```javascript const notifications = new Collection('notifications'); // Method 1: Use returned stopper const stopper = notifications.find({ userId: currentUser._id }) .observe(docs => { updateNotificationBadge(docs.length); }); // Stop single observer stopper.stop(); // Method 2: Stop all observers on cursor const cursor = notifications.find({ userId: currentUser._id }); cursor.observe(docs => console.log('Observer 1')); cursor.observe(docs => console.log('Observer 2')); // Stop all observers at once cursor.stopObservers(); ```