# MongoFlow 🌊
Elegant MongoDB Object Document Mapper (ODM) for Python - with a fluent query builder that makes working with MongoDB a breeze! 🚀
## ✨ Features
- 🎯 **Intuitive Query Builder** - Fluent, chainable queries that feel natural
- âš¡ **High Performance** - Connection pooling, batch operations, and streaming
- 🔧 **Flexible** - Use as simple queries or full ODM with models
- 🎨 **Clean API** - Pythonic, fully typed, and well-documented
- 🚀 **Production Ready** - Battle-tested patterns with automatic retries
- 💾 **Smart Caching** - Optional Redis integration for blazing speed
- 🔄 **Async Support** - Full async/await support with Motor
- 📦 **Lightweight** - Minimal dependencies, maximum functionality
## 📦 Installation
```bash
# Basic installation
pip install mongoflow
# With all features
pip install mongoflow[all]
# With specific features
pip install mongoflow[cache] # Redis caching
pip install mongoflow[validation] # Pydantic validation
pip install mongoflow[async] # Async support
```
## 🚀 Quick Start
### Basic Usage
```python
from mongoflow import MongoFlow, Repository
# Connect to MongoDB
MongoFlow.connect('mongodb://localhost:27017', 'mydb')
# Define a repository
class UserRepository(Repository):
collection_name = 'users'
# Use it!
users = UserRepository()
# Create
user = users.create({
'name': 'John Doe',
'email': 'john@example.com',
'age': 30
})
# Query with fluent builder
active_adults = (users.query()
.where('status', 'active')
.where_greater_than('age', 18)
.order_by('created_at', 'desc')
.limit(10)
.get())
```
### Async Support
```python
import asyncio
from mongoflow import AsyncMongoFlow, AsyncRepository
class AsyncUserRepository(AsyncRepository):
collection_name = 'users'
async def main():
# Connect
await AsyncMongoFlow.connect('mongodb://localhost:27017', 'mydb')
repo = AsyncUserRepository()
# All methods support async/await
user = await repo.create({'name': 'Jane'})
users = await repo.query().where('active', True).get()
# Async streaming for large datasets
async for user in repo.query().stream():
print(user)
asyncio.run(main())
```
## 📚 Query Builder Methods
Both sync and async query builders support the following methods:
### Filtering Methods
```python
# Basic where conditions
.where('field', 'value') # field == value
.where('field', 'value', '$ne') # field != value
.where_in('field', [1, 2, 3]) # field in [1, 2, 3]
.where_not_in('field', [1, 2, 3]) # field not in [1, 2, 3]
.where_between('field', min, max) # min <= field <= max
.where_greater_than('field', value) # field > value
.where_less_than('field', value) # field < value
.where_like('field', 'pattern') # regex pattern matching
.where_null('field') # field is null
.where_not_null('field') # field is not null
.where_exists('field', True) # field exists in document
# Logical operators
.or_where([{'field1': 'value1'}, {'field2': 'value2'}])
.and_where([{'field1': 'value1'}, {'field2': 'value2'}])
```
### Query Modifiers
```python
# Projection
.select('field1', 'field2') # Include only these fields
.exclude('field1', 'field2') # Exclude these fields
# Sorting and pagination
.order_by('field', 'asc') # Sort ascending
.order_by('field', 'desc') # Sort descending
.skip(10) # Skip N documents
.limit(20) # Limit to N documents
.paginate(page=2, per_page=20) # Get paginated results
```
### Execution Methods
```python
# Sync methods
.get() # Get all results
.first() # Get first result
.last() # Get last result
.count() # Count matching documents
.exists() # Check if any documents exist
.distinct('field') # Get distinct values
.stream(batch_size=100) # Stream results
# Async methods (same as above but with await)
await query.get()
await query.first()
await query.last()
await query.count()
await query.exists()
await query.distinct('field')
async for doc in query.stream():
process(doc)
```
### Aggregation Methods
```python
# Simple aggregations
.sum('field') # Sum of field values
.avg('field') # Average of field values
.min('field') # Minimum value
.max('field') # Maximum value
# Group operations
.group('status', {'count': {'$sum': 1}}) # Group by field
.group(
{'status': '$status', 'type': '$type'}, # Group by multiple fields
{'total': {'$sum': '$amount'}} # With aggregations
)
# Custom aggregation pipelines
.aggregate([
{'$match': {'status': 'active'}},
{'$group': {'_id': '$category', 'total': {'$sum': '$amount'}}}
])
```
### Async-Specific Features
All the above methods work with async query builders, just remember to use `await`:
```python
# Async examples
users = await users.query().where('active', True).get()
count = await users.query().where_between('age', 18, 65).count()
stats = await users.query().group('role', {'count': {'$sum': 1}})
# Async streaming
async for user in users.query().where('status', 'active').stream():
await process_user(user)
Raw data
{
"_id": null,
"home_page": null,
"name": "mongoflow",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "mongodb, odm, orm, database, nosql, query-builder, mongoflow, motor, async, pymongo",
"author": null,
"author_email": "Caio Norder <caio@caionorder.com>",
"download_url": "https://files.pythonhosted.org/packages/26/f3/9799fb78c7106f2387b536a7e8303f8ba9a4d569e8e6cc59285b4c251e8d/mongoflow-0.0.2.tar.gz",
"platform": null,
"description": "# MongoFlow \ud83c\udf0a\n\nElegant MongoDB Object Document Mapper (ODM) for Python - with a fluent query builder that makes working with MongoDB a breeze! \ud83d\ude80\n\n## \u2728 Features\n\n- \ud83c\udfaf **Intuitive Query Builder** - Fluent, chainable queries that feel natural\n- \u26a1 **High Performance** - Connection pooling, batch operations, and streaming\n- \ud83d\udd27 **Flexible** - Use as simple queries or full ODM with models\n- \ud83c\udfa8 **Clean API** - Pythonic, fully typed, and well-documented\n- \ud83d\ude80 **Production Ready** - Battle-tested patterns with automatic retries\n- \ud83d\udcbe **Smart Caching** - Optional Redis integration for blazing speed\n- \ud83d\udd04 **Async Support** - Full async/await support with Motor\n- \ud83d\udce6 **Lightweight** - Minimal dependencies, maximum functionality\n\n## \ud83d\udce6 Installation\n\n```bash\n# Basic installation\npip install mongoflow\n\n# With all features\npip install mongoflow[all]\n\n# With specific features\npip install mongoflow[cache] # Redis caching\npip install mongoflow[validation] # Pydantic validation\npip install mongoflow[async] # Async support\n```\n\n## \ud83d\ude80 Quick Start\n\n### Basic Usage\n\n```python\nfrom mongoflow import MongoFlow, Repository\n\n# Connect to MongoDB\nMongoFlow.connect('mongodb://localhost:27017', 'mydb')\n\n# Define a repository\nclass UserRepository(Repository):\n collection_name = 'users'\n\n# Use it!\nusers = UserRepository()\n\n# Create\nuser = users.create({\n 'name': 'John Doe',\n 'email': 'john@example.com',\n 'age': 30\n})\n\n# Query with fluent builder\nactive_adults = (users.query()\n .where('status', 'active')\n .where_greater_than('age', 18)\n .order_by('created_at', 'desc')\n .limit(10)\n .get())\n```\n\n### Async Support\n\n```python\nimport asyncio\nfrom mongoflow import AsyncMongoFlow, AsyncRepository\n\nclass AsyncUserRepository(AsyncRepository):\n collection_name = 'users'\n\nasync def main():\n # Connect\n await AsyncMongoFlow.connect('mongodb://localhost:27017', 'mydb')\n \n repo = AsyncUserRepository()\n \n # All methods support async/await\n user = await repo.create({'name': 'Jane'})\n users = await repo.query().where('active', True).get()\n \n # Async streaming for large datasets\n async for user in repo.query().stream():\n print(user)\n\nasyncio.run(main())\n```\n\n## \ud83d\udcda Query Builder Methods\n\nBoth sync and async query builders support the following methods:\n\n### Filtering Methods\n\n```python\n# Basic where conditions\n.where('field', 'value') # field == value\n.where('field', 'value', '$ne') # field != value\n.where_in('field', [1, 2, 3]) # field in [1, 2, 3]\n.where_not_in('field', [1, 2, 3]) # field not in [1, 2, 3]\n.where_between('field', min, max) # min <= field <= max\n.where_greater_than('field', value) # field > value\n.where_less_than('field', value) # field < value\n.where_like('field', 'pattern') # regex pattern matching\n.where_null('field') # field is null\n.where_not_null('field') # field is not null\n.where_exists('field', True) # field exists in document\n\n# Logical operators\n.or_where([{'field1': 'value1'}, {'field2': 'value2'}])\n.and_where([{'field1': 'value1'}, {'field2': 'value2'}])\n```\n\n### Query Modifiers\n\n```python\n# Projection\n.select('field1', 'field2') # Include only these fields\n.exclude('field1', 'field2') # Exclude these fields\n\n# Sorting and pagination\n.order_by('field', 'asc') # Sort ascending\n.order_by('field', 'desc') # Sort descending\n.skip(10) # Skip N documents\n.limit(20) # Limit to N documents\n.paginate(page=2, per_page=20) # Get paginated results\n```\n\n### Execution Methods\n\n```python\n# Sync methods\n.get() # Get all results\n.first() # Get first result\n.last() # Get last result\n.count() # Count matching documents\n.exists() # Check if any documents exist\n.distinct('field') # Get distinct values\n.stream(batch_size=100) # Stream results\n\n# Async methods (same as above but with await)\nawait query.get()\nawait query.first()\nawait query.last()\nawait query.count()\nawait query.exists()\nawait query.distinct('field')\nasync for doc in query.stream():\n process(doc)\n```\n\n### Aggregation Methods\n\n```python\n# Simple aggregations\n.sum('field') # Sum of field values\n.avg('field') # Average of field values\n.min('field') # Minimum value\n.max('field') # Maximum value\n\n# Group operations\n.group('status', {'count': {'$sum': 1}}) # Group by field\n.group(\n {'status': '$status', 'type': '$type'}, # Group by multiple fields\n {'total': {'$sum': '$amount'}} # With aggregations\n)\n\n# Custom aggregation pipelines\n.aggregate([\n {'$match': {'status': 'active'}},\n {'$group': {'_id': '$category', 'total': {'$sum': '$amount'}}}\n])\n```\n\n### Async-Specific Features\n\nAll the above methods work with async query builders, just remember to use `await`:\n\n```python\n# Async examples\nusers = await users.query().where('active', True).get()\ncount = await users.query().where_between('age', 18, 65).count()\nstats = await users.query().group('role', {'count': {'$sum': 1}})\n\n# Async streaming\nasync for user in users.query().where('status', 'active').stream():\n await process_user(user)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Elegant MongoDB Object Document Mapper (ODM) for Python - fluent query builder included",
"version": "0.0.2",
"project_urls": {
"Bug Tracker": "https://github.com/caionorder/mongoflow/issues",
"Changelog": "https://github.com/caionorder/mongoflow/blob/main/CHANGELOG.md",
"Documentation": "https://mongoflow.readthedocs.io",
"Homepage": "https://github.com/caionorder/mongoflow",
"Source Code": "https://github.com/caionorder/mongoflow"
},
"split_keywords": [
"mongodb",
" odm",
" orm",
" database",
" nosql",
" query-builder",
" mongoflow",
" motor",
" async",
" pymongo"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "61894b12c8b0c3251e1b647a9c1e183f5383fbc4ee1d15a0f89043738655335e",
"md5": "cd73d7abb8c34acec58daba91c5e99af",
"sha256": "8790daf7a1284b3b9d6776deacac5b15f092bd45c68f0a25ed3791724e5258bf"
},
"downloads": -1,
"filename": "mongoflow-0.0.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "cd73d7abb8c34acec58daba91c5e99af",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 38949,
"upload_time": "2025-08-26T12:05:41",
"upload_time_iso_8601": "2025-08-26T12:05:41.308455Z",
"url": "https://files.pythonhosted.org/packages/61/89/4b12c8b0c3251e1b647a9c1e183f5383fbc4ee1d15a0f89043738655335e/mongoflow-0.0.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "26f39799fb78c7106f2387b536a7e8303f8ba9a4d569e8e6cc59285b4c251e8d",
"md5": "82677470bc2677d23391e9a2c5337ee6",
"sha256": "c52018745d0acfb5d5377ab06375614a971c2536724f9128c8063c55b21de821"
},
"downloads": -1,
"filename": "mongoflow-0.0.2.tar.gz",
"has_sig": false,
"md5_digest": "82677470bc2677d23391e9a2c5337ee6",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 40602,
"upload_time": "2025-08-26T12:05:42",
"upload_time_iso_8601": "2025-08-26T12:05:42.926483Z",
"url": "https://files.pythonhosted.org/packages/26/f3/9799fb78c7106f2387b536a7e8303f8ba9a4d569e8e6cc59285b4c251e8d/mongoflow-0.0.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-26 12:05:42",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "caionorder",
"github_project": "mongoflow",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "pymongo",
"specs": []
},
{
"name": "python-dateutil",
"specs": []
}
],
"lcname": "mongoflow"
}