@tranquochung6810/cosmos-connector
v1.0.20
Published
A lightweight library for connecting to and querying Azure Cosmos DB with MongoDB-style filter syntax. Simplifies building complex queries with a fluent API.
Readme
lib-cosmos-connector
A lightweight library for connecting to and querying Azure Cosmos DB with MongoDB-style filter syntax. Simplifies building complex queries with a fluent API.
Installation
npm install @uptime/cosmos-connectorFeatures
- MongoDB-style filter syntax for Azure Cosmos DB
- Fluent query builder API
- Support for pagination, sorting, and filtering
- Methods for CRUD operations
- Bulk operations support
- Easy request parameter integration
Getting Started
Basic Connection
const { CosmosDBConnector } = require('@uptime/cosmos-connector');
// Initialize the connector
const connector = new CosmosDBConnector(
'https://your-cosmos-account.documents.azure.com:443/',
'your-master-key',
5000 // Optional request timeout in ms
);
// Create a query builder for a specific database and container
const queryBuilder = connector.createQueryBuilder('your-database-id', 'your-container-id');Simple Queries
// Get all documents
const allDocs = await connector.searchDocuments('your-database-id', 'your-container-id', { query: 'SELECT * FROM c', parameters: []});
// Get a single document by ID
const item = await connector.readDocument('your-database-id', 'your-container-id', 'document-id');
// Create a document
const newDoc = {
id: 'unique-id',
name: 'New Document',
category: 'example',
createdAt: new Date().toISOString()
};
const createdDoc = await connector.createDocument('your-database-id', 'your-container-id', newDoc);
// Update a document
const updatedDoc = await connector.updateDocument('your-database-id', 'your-container-id', {
id: 'unique-id',
name: 'Updated Document'
});
// Delete a document
await connector.deleteDocument('your-database-id', 'your-container-id', 'document-id');Using the Query Builder
Basic Filtering
// Get active users
const activeUsers = await connector.createQueryBuilder('mydb', 'users')
.where({ status: 'active' })
.getMany();
// Get products with price greater than 100
const expensiveProducts = await connector.createQueryBuilder('mydb', 'products')
.where({ price: { $gt: 100 } })
.getMany();
// Find documents created in the last 7 days
const oneWeekAgo = new Date();
oneWeekAgo.setDate(oneWeekAgo.getDate() - 7);
const recentDocs = await connector.createQueryBuilder('mydb', 'documents')
.where({ createdAt: { $gte: oneWeekAgo.toISOString() } })
.getMany();Logical Operators
// Using the $or operator for documents matching either condition
const result = await connector.createQueryBuilder('mydb', 'products')
.where({
$or: {
category: 'electronics',
price: { $lt: 50 }
}
})
.getMany();
// Using nested $or operators for complex conditions
const complexResult = await connector.createQueryBuilder('mydb', 'products')
.where({
$or: {
category: { $in: ['electronics', 'gadgets'] },
brand: {
$or: {
name: 'Apple',
country: 'USA'
}
}
}
})
.getMany();
// Combining $or with $and implicitly
const mixedQuery = await connector.createQueryBuilder('mydb', 'products')
.where({
status: 'active', // AND condition
$or: { // OR conditions
price: { $lt: 50 },
sale: true
}
})
.getMany();Combining Conditions
// Find active users over 18 years old
const activeAdults = await connector.createQueryBuilder('mydb', 'users')
.where({ status: 'active' })
.andWhere({ age: { $gte: 18 } })
.getMany();
// Find premium users OR users with admin role
const specialUsers = await connector.createQueryBuilder('mydb', 'users')
.where({ accountType: 'premium' })
.orWhere({ role: 'admin' })
.getMany();
// Complex condition: active users who are either premium or have admin role
const complexQuery = await connector.createQueryBuilder('mydb', 'users')
.where({ status: 'active' })
.andWhere(
connector.createQueryBuilder()
.where({ accountType: 'premium' })
.orWhere({ role: 'admin' })
.getQuery()
)
.getMany();Pagination and Sorting
// Get the second page of results with 20 items per page, sorted by name
const pagedResults = await connector.createQueryBuilder('mydb', 'products')
.where({ category: 'electronics' })
.orderBy('name')
.take(20) // LIMIT
.offset(20) // OFFSET (skip first 20)
.getMany();
// Get both the results and total count for pagination
const { items, count } = await connector.createQueryBuilder('mydb', 'products')
.where({ category: 'electronics' })
.orderBy('price', 'DESC')
.take(10)
.getManyAndCount();Array Operations
// Find documents with tags containing 'javascript'
const jsDocs = await connector.createQueryBuilder('mydb', 'articles')
.where({ tags: { $arrayContains: 'javascript' } })
.getMany();
// Find documents with any of the specified tags
const techDocs = await connector.createQueryBuilder('mydb', 'articles')
.where({ tags: { $arrayContainsAny: ['javascript', 'nodejs', 'react'] } })
.getMany();
// Find documents with all of the specified tags
const fullStackDocs = await connector.createQueryBuilder('mydb', 'articles')
.where({ tags: { $arrayContainsAll: ['frontend', 'backend', 'database'] } })
.getMany();String Operations
// Find users with names starting with 'J'
const jUsers = await connector.createQueryBuilder('mydb', 'users')
.where({ name: { $startsWith: 'J' } })
.getMany();
// Find products with description containing 'wireless'
const wirelessProducts = await connector.createQueryBuilder('mydb', 'products')
.where({ description: { $contains: 'wireless' } })
.getMany();
// Find companies not ending with 'Inc'
const nonIncCompanies = await connector.createQueryBuilder('mydb', 'companies')
.where({ name: { $notEndsWith: 'Inc' } })
.getMany();Type Checking
// Find documents where tags is an array
const docsWithTags = await connector.createQueryBuilder('mydb', 'documents')
.where({ tags: { $isArray: true } })
.getMany();
// Find documents where price is a number
const validProducts = await connector.createQueryBuilder('mydb', 'products')
.where({ price: { $isNumber: true } })
.getMany();
// Find documents where description is defined
const describedDocs = await connector.createQueryBuilder('mydb', 'products')
.where({ description: { $isDefined: true } })
.getMany();Integration with Web Applications
Request Query Schema
?page=&page_size=&sort_order=&order_by=&filter={}&search={"keyword":"","scope":""}
Request Body Schema
{
"page": 1,
"pageSize": 20,
"sortOrder": "",
"orderBy": "DESC|ASC",
"filter":{...},
"search":{"keyword": "", "scope": [""]}
}Express.js Example
const express = require('express');
const { CosmosDBConnector } = require('@uptime/cosmos-connector');
const app = express();
app.use(express.json());
// Initialize connector
const connector = new CosmosDBConnector(
process.env.COSMOS_ENDPOINT,
process.env.COSMOS_KEY
);
// Get products with filtering, sorting and pagination
app.get('/api/products', async (req, res) => {
try {
const queryBuilder = connector.createQueryBuilder('catalog', 'products');
// Build query from request query parameters
queryBuilder.buildFromQuery(req.query);
// Get results with count for pagination
const { items, count } = await queryBuilder.getManyAndCount();
res.json({
data: items,
total: count,
page: parseInt(req.query.page) || 1,
pageSize: parseInt(req.query.page_size) || 10
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// Example API endpoint to create a product
app.post('/api/products', async (req, res) => {
try {
const product = req.body;
// Generate ID if not provided
if (!product.id) {
product.id = Date.now().toString();
}
// Add metadata
product.createdAt = new Date().toISOString();
const result = await connector.createDocument('catalog', 'products', product);
res.status(201).json(result);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.listen(3000, () => console.log('Server running on port 3000'));Complex Filters
// Using where with MongoDB-style filter
queryBuilder.where({
status: 'active',
age: { $gte: 18 },
tags: { $in: ['javascript', 'nodejs'] },
price: { $between: [10, 100] }
});
// Using where with direct SQL condition
queryBuilder.where(`
c.status = @status AND
c.age >= @minAge AND
ARRAY_CONTAINS(@tags, c.tags) AND
c.price >= @minPrice AND c.price <= @maxPrice
`, {
status: 'active',
minAge: 18,
tags: ['javascript', 'nodejs'],
minPrice: 10,
maxPrice: 100
});Nested Objects
// Using where with MongoDB-style filter
queryBuilder.where({
'user.name': 'John',
'user.age': { $gt: 18 }
});
// Using where with direct SQL condition
queryBuilder.where(`
c.user.name = @userName AND
c.user.age > @userAge
`, {
userName: 'John',
userAge: 18
});Supported Operators
Comparison Operators
$eq: Equal to$ne: Not equal to$gt: Greater than$gte: Greater than or equal to$lt: Less than$lte: Less than or equal to$between: Between two values (requires an array with two values)$notBetween: Not between two values (requires an array with two values)
Array Operators
$in: In an array of values$nin: Not in an array of values$arrayContains: Array contains a value$arrayContainsAny: Array contains any of the values$arrayContainsAll: Array contains all of the values$arrayLength: Array length equals a value
String Operators
$like: String contains a value$notLike: String does not contain a value$contains: String contains a value$startsWith: String starts with a value$notStartsWith: String does not start with a value$endsWith: String ends with a value$notEndsWith: String does not end with a value
Type Checking Operators
$isArray: Is an array$isNotArray: Is not an array$isBool: Is a boolean$isNotBool: Is not a boolean$isDefined: Is defined$isNotDefined: Is not defined$isInteger: Is an integer$isNull: Is null$isNumber: Is a number$isString: Is a string$isObject: Is an object
License
ISC
