{"id":19700422,"url":"https://github.com/kenjyco/mongo-helper","last_synced_at":"2026-01-28T13:36:32.431Z","repository":{"id":54609046,"uuid":"178716324","full_name":"kenjyco/mongo-helper","owner":"kenjyco","description":"Helper funcs and tools for working with MongoDB","archived":false,"fork":false,"pushed_at":"2025-07-23T19:20:35.000Z","size":91,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-28T15:01:17.930Z","etag":null,"topics":["aggregation-pipeline","data","database","kenjyco","mongo","mongodb","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kenjyco.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-03-31T16:55:56.000Z","updated_at":"2025-07-23T19:20:13.000Z","dependencies_parsed_at":"2024-09-09T12:54:42.678Z","dependency_job_id":"2d142512-e416-42db-a4d2-1aa14b85544b","html_url":"https://github.com/kenjyco/mongo-helper","commit_stats":{"total_commits":62,"total_committers":1,"mean_commits":62.0,"dds":0.0,"last_synced_commit":"f0507fbf65b647985aaf493154d2f3d4d5e35175"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/kenjyco/mongo-helper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kenjyco%2Fmongo-helper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kenjyco%2Fmongo-helper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kenjyco%2Fmongo-helper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kenjyco%2Fmongo-helper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kenjyco","download_url":"https://codeload.github.com/kenjyco/mongo-helper/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kenjyco%2Fmongo-helper/sbom","scorecard":{"id":555167,"data":{"date":"2025-08-11","repo":{"name":"github.com/kenjyco/mongo-helper","commit":"b42d142a4e8a232cfd8e3b102f319dda360b7e27"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4,"checks":[{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":10,"reason":"17 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":8,"reason":"2 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-m87m-mmvp-v9qm","Warn: Project is vulnerable to: PYSEC-2013-30 / GHSA-x33v-f3gp-gw2c"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-20T12:07:24.268Z","repository_id":54609046,"created_at":"2025-08-20T12:07:24.269Z","updated_at":"2025-08-20T12:07:24.269Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28846053,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-28T13:02:32.985Z","status":"ssl_error","status_checked_at":"2026-01-28T13:02:04.945Z","response_time":57,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aggregation-pipeline","data","database","kenjyco","mongo","mongodb","python"],"created_at":"2024-11-11T21:05:58.896Z","updated_at":"2026-01-28T13:36:32.425Z","avatar_url":"https://github.com/kenjyco.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"A streamlined Python library for MongoDB operations that prioritizes developer productivity and mental load reduction. mongo-helper wraps PyMongo with intuitive interfaces, automatic connection management, and convenient helper functions that eliminate boilerplate code common in MongoDB workflows. It also provides a simple way to build up [aggregation pipeline queries](https://www.mongodb.com/docs/manual/core/aggregation-pipeline).\n\nThe library is designed around the philosophy that database interactions should be simple, readable, and predictable. It provides both low-level control through the `Mongo` class and high-level convenience through the `Collection` wrapper, allowing developers to choose the appropriate abstraction level for their use case. mongo-helper integrates seamlessly with Docker-based development workflows and includes comprehensive query helpers for time-based data analysis.\n\nThis library is ideal for data engineers, analysts, and developers who work regularly with MongoDB and want to minimize the cognitive overhead of database operations while maintaining full access to MongoDB's capabilities. It fits naturally into data processing pipelines, analytics workflows, and rapid prototyping environments where developer velocity is crucial.\n\nTested for Python 3.5 - 3.13 against MongoDB 4.4 docker container.\n\nConnect with a DB url in the following format:\n\n- mongodb://someuser:somepassword@somehost:27017/admin\n\n\u003e See \u003chttps://docs.mongodb.com/manual/reference/connection-string\u003e for connecting to a replica-set/cluster.\n\u003e\n\u003e Use percent encoding if your username or password includes `@`, `:`, `/`, or `%`.\n\n## Install\n\n```\npip install mongo-helper\n```\n\n## Configuration\n\nmongo-helper uses a settings.ini file for Docker and connection configuration:\n\n```ini\n[default]\nmongo_image_version = 4.4\nmongo_username = mongouser\nmongo_password = some.pass\nquery_db = db\nuse_none_cert = False\nconnect_timeout = 5\nmongo_url =\n\n[dev]\ncontainer_name = mongo-helper\nport = 27017\nrm = False\nmongo_data_dir =\nmongo_url = mongodb://mongouser:some.pass@localhost:27017/admin\n\n[test]\ncontainer_name = mongo-helper-test\nport = 27001\nrm = True\nmongo_data_dir =\nmongo_url = mongodb://mongouser:some.pass@localhost:27001/admin\n```\n\n\u003e On first use, the default settings.ini file is copied to `~/.config/mongo-helper/settings.ini`\n\n## QuickStart\n\n```python\nimport mongo_helper as mh\n\n# Connect automatically using settings.ini configuration\nmongo, total_docs = mh.connect_to_server()\n\n# Use the high-level Collection wrapper for common operations\nusers = mh.Collection('users')\n\n# Insert documents with minimal syntax\nuser_id = users.insert_one({'name': 'Alice', 'age': 30, 'status': 'active'})\n\n# Query with convenient field selection\nactive_users = users.find({'status': 'active'}, fields='name, age', to_list=True)\n\n# Count documents matching criteria\nuser_count = users.count({'age': {'$gte': 18}})\n\n# Time-based queries using helper functions\nrecent_users = users.find(mh.get_days_ago_query(days_ago=7), to_list=True)\n\nprint(f\"Found {len(active_users)} active users out of {user_count} total adults\")\nprint(f\"Recent signups: {len(recent_users)}\")\n```\n\nThis example demonstrates mongo-helper's key value propositions: automatic connection handling, simplified syntax for common operations, convenient field projection syntax, and time-based query helpers. You get MongoDB's full power with significantly less boilerplate code and mental overhead.\n\n## API Overview\n\n### Connection Management\n\n**`connect_to_server(url=None, db=None, use_none_cert=None, attempt_docker=True, exception=False, show=False)`** - Connect to MongoDB server and return Mongo instance\n- `url`: MongoDB connection URL, defaults to mongo_url from settings\n- `db`: database name, defaults to query_db from settings\n- `use_none_cert`: SSL certificate setting, defaults to use_none_cert from settings\n- `attempt_docker`: if True, automatically start Docker container on connection failure\n- `exception`: if True, raise exceptions on connection failure\n- `show`: if True, display Docker commands and output\n- Returns: tuple of (mongo_instance, total_documents_in_database) on success, (None, float('inf')) on failure\n- Internal calls: `start_docker()`, `Mongo()`, `mongo.get_collections()`, `mongo.total_documents()`\n\n**`start_docker(exception=False, show=False, force=False, wait=True, sleeptime=2)`** - Start MongoDB Docker container using settings.ini values\n- `exception`: if True, raise exception on Docker errors\n- `show`: if True, display Docker commands and output\n- `force`: if True, stop and remove existing container before creating new one\n- `wait`: if True, wait until MongoDB accepts connections\n- `sleeptime`: seconds to sleep between connection checks when waiting\n- Returns: result from bg_helper Docker functions\n- Internal calls: `_settings_for_docker_ok()`, `bh.tools.docker_mongo_start()`\n\n**`stop_docker(exception=False, show=False)`** - Stop MongoDB Docker container using settings.ini values\n- `exception`: if True, raise exception on Docker errors\n- `show`: if True, display Docker commands and output\n- Returns: result from bg_helper Docker functions\n- Internal calls: `_settings_for_docker_ok()`, `bh.tools.docker_stop()`\n\n### High-Level Collection Interface\n\n**`Collection(collection_name, mongo_instance=None, url=None, db=None, use_none_cert=None, attempt_docker=True, exception=True, show=False)`** - Convenient wrapper for MongoDB collection operations\n- `collection_name`: name of MongoDB collection to work with\n- `mongo_instance`: optional Mongo instance to use, creates one automatically if None\n- `url`: MongoDB connection URL for automatic connection\n- `db`: database name for automatic connection\n- `use_none_cert`: SSL certificate setting for automatic connection\n- `attempt_docker`: whether to attempt Docker startup for automatic connection\n- `exception`: whether to raise exceptions for automatic connection\n- `show`: whether to show output for automatic connection\n- Internal calls: `mh.connect_to_server()`, `mongo.change_database()`\n\n**`Collection.insert_one(document)`** - Add a document to the collection and return inserted_id\n- `document`: dict of information to be inserted\n- Returns: ObjectId of inserted document\n- Internal calls: `mongo._insert_one()`\n\n**`Collection.insert_many(documents)`** - Add several documents to the collection and return inserted_ids\n- `documents`: list of dicts to insert\n- Returns: list of ObjectIds for inserted documents\n- Internal calls: `mongo._insert_many()`\n\n**`Collection.find(query={}, fields='', ignore_fields='', to_list=False, **kwargs)`** - Return documents matching the query\n- `query`: dict representing search criteria\n- `fields`: string containing fields to return, separated by any of , ; |\n- `ignore_fields`: string containing fields to ignore, separated by any of , ; |\n- `to_list`: if True, return list instead of cursor\n- `kwargs`: additional arguments passed to underlying _find method\n- Returns: cursor or list of documents\n- Internal calls: `mongo._find()`\n\n**`Collection.find_one(query={}, fields='', ignore_fields='', **kwargs)`** - Return a single document matching the query\n- `query`: dict representing search criteria\n- `fields`: string containing fields to return, separated by any of , ; |\n- `ignore_fields`: string containing fields to ignore, separated by any of , ; |\n- `kwargs`: additional arguments passed to underlying _find_one method\n- Returns: dict (single document) or string (if single field requested)\n- Internal calls: `mongo._find_one()`\n\n**`Collection.update_one(match, update, upsert=False)`** - Update one matching document and return number modified\n- `match`: dict of query matching document to update\n- `update`: dict of modifications to apply\n- `upsert`: if True, perform insert if no documents match\n- Returns: number of documents modified\n- Internal calls: `mongo._update_one()`\n\n**`Collection.update_many(match, update, upsert=False)`** - Update all matching documents and return number modified\n- `match`: dict of query matching documents to update\n- `update`: dict of modifications to apply\n- `upsert`: if True, perform insert if no documents match\n- Returns: number of documents modified\n- Internal calls: `mongo._update_many()`\n\n**`Collection.delete_one(match)`** - Delete one matching document and return number deleted\n- `match`: dict of query matching document to delete\n- Returns: number of documents deleted\n- Internal calls: `mongo._delete_one()`\n\n**`Collection.delete_many(match)`** - Delete all matching documents and return number deleted\n- `match`: dict of query matching documents to delete\n- Returns: number of documents deleted\n- Internal calls: `mongo._delete_many()`\n\n**`Collection.count(match={}, **kwargs)`** - Return count of documents matching criteria\n- `match`: dict of query matching documents to count\n- `kwargs`: additional arguments passed to underlying _count method\n- Returns: integer count of matching documents\n- Internal calls: `mongo._count()`\n\n**`Collection.distinct(key, match={}, **kwargs)`** - Return list of distinct values for key among documents\n- `key`: field name to get distinct values for\n- `match`: dict of query matching documents\n- `kwargs`: additional arguments passed to underlying _distinct method\n- Returns: list of distinct values\n- Internal calls: `mongo._distinct()`\n\n**`Collection.bulk_write(operations, ordered=True, bypass_document_validation=False, debug=False)`** - Execute mixed write operations and return result\n- `operations`: list of write operation objects (InsertOne, UpdateOne, UpdateMany, ReplaceOne, DeleteOne, DeleteMany)\n- `ordered`: if True, execute in order and stop after first error\n- `bypass_document_validation`: if True, bypass document validation\n- `debug`: if True, drop into debugger on BulkWriteError\n- Returns: BulkWriteResult object with operation information\n- Internal calls: `mongo._bulk_write()`\n\n### Low-Level Database Interface\n\n**`Mongo(url=None, db=None, use_none_cert=None)`** - Instance that can execute MongoDB statements\n- `url`: MongoDB connection URL, defaults to mongo_url from settings\n- `db`: database name for queries, defaults to query_db from settings\n- `use_none_cert`: if True, add \"\u0026ssl_cert_reqs=CERT_NONE\" to URL for SSL connections\n- Internal calls: `SETTINGS.get()`, `MongoClient()`\n\n**`Mongo.get_databases(system=False)`** - Return list of database names\n- `system`: if True, include system databases ('admin', 'config', 'local')\n- Returns: list of database name strings\n- Internal calls: `self._client.list_database_names()`\n\n**`Mongo.get_collections(db=None)`** - Return list of collection names\n- `db`: database name, uses current self._db if None\n- Returns: list of collection name strings\n- Internal calls: `self._client[db].list_collection_names()`\n\n**`Mongo.change_database(db)`** - Set different database to use for queries\n- `db`: database name to switch to\n- Internal calls: sets `self._db`\n\n**`Mongo.select_database(system=False)`** - Interactively select database to use for queries\n- `system`: if True, include system databases in selection menu\n- Internal calls: `ih.make_selections()`, `self.get_databases()`\n\n### Database Statistics and Information\n\n**`Mongo.db_stats(scale='bytes')`** - Return dict of database information\n- `scale`: one of bytes, KB, MB, GB (note: avgObeSize always in bytes)\n- Returns: dict with database statistics\n- Internal calls: `self._command('dbStats')`\n\n**`Mongo.coll_stats(collection, ignore_fields='wiredTiger, indexDetails', scale='bytes')`** - Return dict of collection information\n- `collection`: collection name\n- `ignore_fields`: string of output fields to ignore, separated by , ; |\n- `scale`: one of bytes, KB, MB, GB (note: avgObeSize always in bytes)\n- Returns: dict with collection statistics\n- Internal calls: `self._command('collStats')`, `ih.ignore_keys()`\n\n**`Collection.coll_stats(ignore_fields='wiredTiger, indexDetails', scale='bytes')`** - Return dict of collection information\n- `ignore_fields`: string of output fields to ignore, separated by , ; |\n- `scale`: one of bytes, KB, MB, GB (note: avgObeSize always in bytes)\n- Returns: dict with collection statistics\n- Internal calls: `mongo.coll_stats()`\n\n**`Mongo.server_status(ignore_fields='wiredTiger, tcmalloc, metrics, logicalSessionRecordCache')`** - Return dict from serverStatus command\n- `ignore_fields`: string of output fields to ignore, separated by , ; |\n- Returns: dict with server status information\n- Internal calls: `self._command('serverStatus')`, `ih.ignore_keys()`\n\n**`Mongo.server_info(ignore_fields='buildEnvironment')`** - Return dict from client server_info\n- `ignore_fields`: string of output fields to ignore, separated by , ; |\n- Returns: dict with server information\n- Internal calls: `self._client.server_info()`, `ih.ignore_keys()`\n\n### Index Management\n\n**`Collection.create_index(keys, unique=False, ttl=None, sparse=False, background=False, **kwargs)`** - Create index on collection\n- `keys`: list of 2-item tuples with field name and direction (1 ascending, -1 descending)\n- `unique`: if True, create uniqueness constraint\n- `ttl`: time to live in seconds for documents\n- `sparse`: if True, only index documents containing the indexed field\n- `background`: if True, create index in background\n- `kwargs`: additional arguments passed to underlying _create_index method\n- Returns: index name\n- Internal calls: `mongo._create_index()`\n\n**`Collection.drop_index(name, **kwargs)`** - Drop index from collection\n- `name`: name of index to drop\n- `kwargs`: additional arguments passed to underlying method\n- Internal calls: `mongo._drop_index()`\n\n**`Collection.index_information()`** - Return dict of index information for collection\n- Returns: dict with index information\n- Internal calls: `mongo._index_information()`\n\n**`Collection.index_names()`** - Return list of index names\n- Returns: sorted list of index name strings\n- Internal calls: `mongo._index_names()`\n\n**`Collection.index_sizes(scale='bytes')`** - Return dict of index sizes\n- `scale`: one of bytes, KB, MB, GB\n- Returns: dict mapping index names to sizes\n- Internal calls: `mongo._index_sizes()`\n\n**`Collection.index_usage(name='', full=False)`** - Return index usage statistics\n- `name`: name of specific index to check\n- `full`: if True, return full list of dicts from $indexStats aggregation\n- Returns: list of tuples or dicts with usage statistics\n- Internal calls: `mongo._index_usage()`\n\n### Time-Based Query Helpers\n\n**`get_date_query(date_string, fmt='%Y-%m-%d', timezone=\"America/Chicago\", timestamp_field='_id')`** - Return query dict for matching date in timezone\n- `date_string`: date string to parse\n- `fmt`: format the date_string is in\n- `timezone`: timezone for determining start of day\n- `timestamp_field`: name of timestamp field to query on\n- Returns: dict with MongoDB query for the specified date\n- Internal calls: `dh.date_start_utc()`, `ObjectId.from_datetime()`\n\n**`get_days_ago_query(days_ago=0, until_days_ago=0, timezone=\"America/Chicago\", timestamp_field='_id')`** - Return query dict for matching days ago in timezone\n- `days_ago`: number of days ago to start from\n- `until_days_ago`: number of days ago to end at\n- `timezone`: timezone for day calculations\n- `timestamp_field`: name of timestamp field to query on\n- Returns: dict with MongoDB query for the specified day range\n- Internal calls: `dh.days_ago()`, `ObjectId.from_datetime()`\n\n**`get_hours_ago_query(hours_ago=1, until_hours_ago=0, timestamp_field='_id')`** - Return query dict for matching hours ago\n- `hours_ago`: number of hours ago to start from\n- `until_hours_ago`: number of hours ago to end at\n- `timestamp_field`: name of timestamp field to query on\n- Returns: dict with MongoDB query for the specified hour range\n- Internal calls: `dh.utc_now_localized()`, `dh.timedelta()`, `ObjectId.from_datetime()`\n\n**`get_minutes_ago_query(minutes_ago=1, until_minutes_ago=0, timestamp_field='_id')`** - Return query dict for matching minutes ago\n- `minutes_ago`: number of minutes ago to start from\n- `until_minutes_ago`: number of minutes ago to end at\n- `timestamp_field`: name of timestamp field to query on\n- Returns: dict with MongoDB query for the specified minute range\n- Internal calls: `dh.utc_now_localized()`, `dh.timedelta()`, `ObjectId.from_datetime()`\n\n### Utility Methods\n\n**`Collection.first_obj(match={}, timestamp_field='_id', fields='', ignore_fields='', **kwargs)`** - Return first object in collection\n- `match`: query criteria passed to _find_one\n- `timestamp_field`: name of timestamp field to sort on\n- `fields`: string of fields to return, separated by , ; |\n- `ignore_fields`: string of fields to ignore, separated by , ; |\n- `kwargs`: additional arguments passed to underlying method\n- Returns: dict with first document\n- Internal calls: `mongo.first_obj()`\n\n**`Collection.last_obj(match={}, timestamp_field='_id', fields='', ignore_fields='', **kwargs)`** - Return last object in collection\n- `match`: query criteria passed to _find_one\n- `timestamp_field`: name of timestamp field to sort on\n- `fields`: string of fields to return, separated by , ; |\n- `ignore_fields`: string of fields to ignore, separated by , ; |\n- `kwargs`: additional arguments passed to underlying method\n- Returns: dict with last document\n- Internal calls: `mongo.last_obj()`\n\n**`Collection.obj_id_set(match)`** - Return set of ObjectIds for matching documents\n- `match`: dictionary representing documents to match\n- Returns: set of ObjectId values\n- Internal calls: `mongo.obj_id_set()`\n\n**`Collection.total_documents()`** - Return total count of documents in collection\n- Returns: integer count using estimated_document_count\n- Internal calls: `mongo.total_documents()`\n\n### Advanced Operations\n\n**`Mongo._build_pipeline(match=None, group_by=None, timestamp_field='_id', unwind=None, include_array_index=False, projection=None, limit=None, to_set=None, to_list=None, to_sum=None, out=None)`** - Build aggregation pipeline\n- `match`: dictionary for match stage\n- `group_by`: list of keys to group by or string separated by , ; |\n- `timestamp_field`: timestamp field name for sorting when limit specified\n- `unwind`: list of keys to unwind or string separated by , ; |\n- `include_array_index`: if True, include array index in unwind operations\n- `projection`: list of keys to project or string separated by , ; |\n- `limit`: maximum number of items\n- `to_set`: keys to add to set for each group or string separated by , ; |\n- `to_list`: keys to add to list for each group or string separated by , ; |\n- `to_sum`: keys to sum for each group or string separated by , ; |\n- `out`: collection name to save results to\n- Returns: list of pipeline stages for aggregation\n- Internal calls: `ih.get_list_from_arg_strings()`\n\n**`Mongo.ez_pipeline(collection, match, group_by, timestamp_field='_id', unwind=None, include_array_index=False, projection=None, limit=None, to_set=None, to_list=None, to_sum=None, group_action=None, include_condition=None, verbose=False)`** - Build/run aggregation pipeline to group and count data\n- `collection`: collection name\n- `match`: dictionary for match stage\n- `group_by`: list of keys to group by or string separated by , ; |\n- `timestamp_field`: timestamp field for sorting\n- `unwind`: keys to unwind or string separated by , ; |\n- `include_array_index`: if True, include array index in unwind\n- `projection`: keys to project or string separated by , ; |\n- `limit`: maximum items\n- `to_set`: keys to add to set or string separated by , ; |\n- `to_list`: keys to add to list or string separated by , ; |\n- `to_sum`: keys to sum or string separated by , ; |\n- `group_action`: callable mapped over each grouped item\n- `include_condition`: callable returning bool for item inclusion\n- `verbose`: if True, print generated pipeline\n- Returns: dict with keys 'counts', 'data', 'total', 'group_by', 'duration', 'pipeline', 'total_percent'\n- Internal calls: `self._build_pipeline()`, `self._aggregate()`, `dh.utc_now_localized()`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkenjyco%2Fmongo-helper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkenjyco%2Fmongo-helper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkenjyco%2Fmongo-helper/lists"}