Name | atlasq JSON |
Version |
0.15.0
JSON |
| download |
home_page | None |
Summary | Query proxy that allows the usage of AtlasSearch with mongoengine specific syntax |
upload_time | 2024-09-27 14:30:57 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.6 |
license | MIT License Copyright (c) 2022 Certego Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
keywords |
certego
atlas
mongoengine
python
search
textsearch
atlassearch
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# AtlasQ
AtlasQ allows the usage of [AtlasSearch](https://www.mongodb.com/docs/atlas/atlas-search/) keeping the [MongoEngine](https://github.com/MongoEngine/mongoengine) syntax.
## Structure
The package tries to follow the MongoEngine structure;
the major differences reside in the `transform.py` and `queryset.py` files.
### Transform
Like in MongoEngine, a step in the pipeline is the creation of a query from a `Q` object:
we have to find a correspondence between the MongoEngine common syntax and what AtlasSearch allows.
For doing this, we had to find some compromises.
Not every keyword is supported at the moment: if you have an actual use case that you would like to support,
please be free to open an issue or a PR at any moment.
### QuerySet
There are probably a thousand of better implementation, if you actually knew MongoEngine and above all [PyMongo](https://pymongo.readthedocs.io/en/stable/).
Unfortunately, our knowledge is limited, so here we go. If you find a solution that works better, again, feel free to open an issue or a PR.
The main idea, is that the `filter` should work like an `aggregation`.
For doing so, and with keeping the compatibility on how MongoEngine works (i.e. the filter should return a queryset of `Document`) we had to do some work.
Calling `.aggregate` instead has to work as MongoEngine expect, meaning a list of dictionaries.
## Usage
Now the most important part: how do you use this package?
```python3
from mongoengine import Document, fields
from atlasq import AtlasManager, AtlasQ, AtlasQuerySet
index_name = str("my_index")
class MyDocument(Document):
name = fields.StringField(required=True)
surname = fields.StringField(required=True)
atlas = AtlasManager(index_name)
obj = MyDocument.objects.create(name="value", surname="value2")
qs = MyDocument.atlas.filter(name="value")
assert isinstance(qs, AtlasQuerySet)
obj_from_atlas = qs.first()
assert obj == obj_from_atlas
obj2_from_atlas = MyDocument.atlas.get(AtlasQ(name="value") & AtlasQ(surname="value2"))
assert obj == obj2_from_atlas
obj3_from_atlas = MyDocument.atlas.get(AtlasQ(wrong_field="value"))
assert obj3_from_atlas is None
```
## Extended Features
### Validation
We also decided to have, optionally, a validation of the index.
Two things are checked:
- The index actually exists (If you query a non-existing index, Atlas as default behaviour will not raise any error).
- The fields that you are querying are actually indexed(If you query a field that is not indexed, Atlas as default behaviour will not raise any error, and will return an empty list).
To make these check, you need to call the function `ensure_index` on the queryset.
```python3
from mongoengine import Document, fields
from atlasq import AtlasManager, AtlasQ
index_name = str("my_index")
class MyDocument(Document):
name = fields.StringField(required=True)
surname = fields.StringField(required=True)
atlas = AtlasManager(index_name)
result = MyDocument.atlas.ensure_index("user", "pwd", "group", "cluster")
assert result is True
obj1_from_atlas = MyDocument.atlas.get(AtlasQ(name="value"))
obj2_from_atlas = MyDocument.atlas.get(AtlasQ(wrong_field="value")) # raises AtlasIndexFieldError
```
### EmbeddedDocuments
Embedded documents are queried in two different ways, depending on how you created your Search Index.
Remember to ensure the index so that AtlasQ can know how your index is defined
If you used the [embeddedDocuments](https://www.mongodb.com/docs/atlas/atlas-search/define-field-mappings/#std-label-bson-data-types-embedded-documents) type, AtlasQ will use the [embeddedDocument](https://www.mongodb.com/docs/atlas/atlas-search/embedded-document/) query syntax.
Otherwise, if you used the [document](https://www.mongodb.com/docs/atlas/atlas-search/define-field-mappings/#document) type, or you did not ensure the index, a normal `text` search with the `.` syntax will be used.
### Upload index
It is possible to upload directly the Search index using AtlasQ, calling the function `upload_index` on the queryset. Syntax checks on the index itself are performed.
If the `_id` is not present but `pk` or `id` was specified, it will be automatically added, allowing valid text query on the
primary key.
```python3
from mongoengine import Document, fields
from atlasq import AtlasManager
index_name = str("my_index")
index = {
"analyzer": "lucene.keyword",
"mappings": {
"dynamic": False,
"fields": {
"_id": {
"type": "objectId"
},
"name": {
"type": "string"
},
"surname": {
"type": "string"
},
}
}
}
class MyDocument(Document):
name = fields.StringField(required=True)
surname = fields.StringField(required=True)
atlas = AtlasManager(index_name)
result = MyDocument.atlas.ensure_index("user", "pwd", "group", "cluster")
assert result is False
MyDocument.atlas.upload_index(index, "user", "pwd", "group", "cluster")
result = MyDocument.atlas.ensure_index("user", "pwd", "group", "cluster")
assert result is True
```
### Sort
On the [10th of July 2023](https://www.mongodb.com/docs/atlas/atlas-search/changelog/#10-july-2023-release), the `Sort` functionality was released for Atlas search.
AtlasQ, from version 0.12.0, will support this feature inside the `order_by` function.
To have the old behaviour of the order_by (useful if you want to sort _after_ aggregations and not after the search stage), you can set the kwarg `as_aggregation` as `True`.
Raw data
{
"_id": null,
"home_page": null,
"name": "atlasq",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": "Simone Berni <s.berni@certego.net>",
"keywords": "certego, atlas, mongoengine, python, search, textsearch, atlassearch",
"author": null,
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/98/fe/853fce37cdc4c0f13532e34481a66030f2d9c0eecb7b087967a340026714/atlasq-0.15.0.tar.gz",
"platform": null,
"description": "# AtlasQ\nAtlasQ allows the usage of [AtlasSearch](https://www.mongodb.com/docs/atlas/atlas-search/) keeping the [MongoEngine](https://github.com/MongoEngine/mongoengine) syntax.\n\n## Structure\nThe package tries to follow the MongoEngine structure;\nthe major differences reside in the `transform.py` and `queryset.py` files. \n\n### Transform\nLike in MongoEngine, a step in the pipeline is the creation of a query from a `Q` object: \nwe have to find a correspondence between the MongoEngine common syntax and what AtlasSearch allows.\nFor doing this, we had to find some compromises.\n\nNot every keyword is supported at the moment: if you have an actual use case that you would like to support,\nplease be free to open an issue or a PR at any moment.\n\n### QuerySet\nThere are probably a thousand of better implementation, if you actually knew MongoEngine and above all [PyMongo](https://pymongo.readthedocs.io/en/stable/).\nUnfortunately, our knowledge is limited, so here we go. If you find a solution that works better, again, feel free to open an issue or a PR.\n\nThe main idea, is that the `filter` should work like an `aggregation`. \nFor doing so, and with keeping the compatibility on how MongoEngine works (i.e. the filter should return a queryset of `Document`) we had to do some work. \nCalling `.aggregate` instead has to work as MongoEngine expect, meaning a list of dictionaries. \n\n\n\n## Usage\nNow the most important part: how do you use this package?\n\n\n```python3\nfrom mongoengine import Document, fields\n\nfrom atlasq import AtlasManager, AtlasQ, AtlasQuerySet\n\nindex_name = str(\"my_index\")\n\nclass MyDocument(Document):\n name = fields.StringField(required=True)\n surname = fields.StringField(required=True)\n atlas = AtlasManager(index_name)\n\nobj = MyDocument.objects.create(name=\"value\", surname=\"value2\")\n\nqs = MyDocument.atlas.filter(name=\"value\")\nassert isinstance(qs, AtlasQuerySet)\nobj_from_atlas = qs.first()\nassert obj == obj_from_atlas\n\nobj2_from_atlas = MyDocument.atlas.get(AtlasQ(name=\"value\") & AtlasQ(surname=\"value2\"))\nassert obj == obj2_from_atlas\n\n\nobj3_from_atlas = MyDocument.atlas.get(AtlasQ(wrong_field=\"value\"))\nassert obj3_from_atlas is None\n```\n\n## Extended Features\n\n### Validation\nWe also decided to have, optionally, a validation of the index.\nTwo things are checked:\n- The index actually exists (If you query a non-existing index, Atlas as default behaviour will not raise any error).\n- The fields that you are querying are actually indexed(If you query a field that is not indexed, Atlas as default behaviour will not raise any error, and will return an empty list).\nTo make these check, you need to call the function `ensure_index` on the queryset.\n\n```python3\nfrom mongoengine import Document, fields\n\nfrom atlasq import AtlasManager, AtlasQ\n\nindex_name = str(\"my_index\")\n\nclass MyDocument(Document):\n name = fields.StringField(required=True)\n surname = fields.StringField(required=True)\n atlas = AtlasManager(index_name)\n\nresult = MyDocument.atlas.ensure_index(\"user\", \"pwd\", \"group\", \"cluster\")\nassert result is True\nobj1_from_atlas = MyDocument.atlas.get(AtlasQ(name=\"value\")) \nobj2_from_atlas = MyDocument.atlas.get(AtlasQ(wrong_field=\"value\")) # raises AtlasIndexFieldError\n```\n\n### EmbeddedDocuments\nEmbedded documents are queried in two different ways, depending on how you created your Search Index.\nRemember to ensure the index so that AtlasQ can know how your index is defined\nIf you used the [embeddedDocuments](https://www.mongodb.com/docs/atlas/atlas-search/define-field-mappings/#std-label-bson-data-types-embedded-documents) type, AtlasQ will use the [embeddedDocument](https://www.mongodb.com/docs/atlas/atlas-search/embedded-document/) query syntax.\nOtherwise, if you used the [document](https://www.mongodb.com/docs/atlas/atlas-search/define-field-mappings/#document) type, or you did not ensure the index, a normal `text` search with the `.` syntax will be used.\n\n### Upload index\nIt is possible to upload directly the Search index using AtlasQ, calling the function `upload_index` on the queryset. Syntax checks on the index itself are performed.\nIf the `_id` is not present but `pk` or `id` was specified, it will be automatically added, allowing valid text query on the\nprimary key.\n\n```python3\nfrom mongoengine import Document, fields\n\nfrom atlasq import AtlasManager\n\nindex_name = str(\"my_index\")\nindex = {\n \"analyzer\": \"lucene.keyword\",\n \"mappings\": {\n \"dynamic\": False,\n \"fields\": {\n \"_id\": {\n \"type\": \"objectId\"\n },\n \"name\": {\n \"type\": \"string\"\n },\n \"surname\": {\n \"type\": \"string\"\n },\n }\n }\n}\nclass MyDocument(Document):\n name = fields.StringField(required=True)\n surname = fields.StringField(required=True)\n atlas = AtlasManager(index_name)\n\nresult = MyDocument.atlas.ensure_index(\"user\", \"pwd\", \"group\", \"cluster\")\nassert result is False\nMyDocument.atlas.upload_index(index, \"user\", \"pwd\", \"group\", \"cluster\")\nresult = MyDocument.atlas.ensure_index(\"user\", \"pwd\", \"group\", \"cluster\")\nassert result is True\n\n```\n\n\n### Sort\nOn the [10th of July 2023](https://www.mongodb.com/docs/atlas/atlas-search/changelog/#10-july-2023-release), the `Sort` functionality was released for Atlas search.\n\nAtlasQ, from version 0.12.0, will support this feature inside the `order_by` function.\nTo have the old behaviour of the order_by (useful if you want to sort _after_ aggregations and not after the search stage), you can set the kwarg `as_aggregation` as `True`.\n",
"bugtrack_url": null,
"license": "MIT License Copyright (c) 2022 Certego Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ",
"summary": "Query proxy that allows the usage of AtlasSearch with mongoengine specific syntax",
"version": "0.15.0",
"project_urls": {
"documentation": "https://github.com/certego/atlasq/README.md",
"homepage": "https://github.com/certego/atlasq",
"repository": "https://github.com/certego/atlasq",
"source": "https://github.com/certego/atlasq",
"tracker": "https://github.com/certego/atlasq/issues"
},
"split_keywords": [
"certego",
" atlas",
" mongoengine",
" python",
" search",
" textsearch",
" atlassearch"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "fde99ae1d7ed6f7a45041c68d5dd41b32f330ee51de9325e5028624f25d83534",
"md5": "5ace11d216efb6e9028cc4af7a77be0a",
"sha256": "bc22a04e82b82890c8377bd5bc4dcc463390a39238efd8c91e47b9535864934c"
},
"downloads": -1,
"filename": "atlasq-0.15.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "5ace11d216efb6e9028cc4af7a77be0a",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 16091,
"upload_time": "2024-09-27T14:30:55",
"upload_time_iso_8601": "2024-09-27T14:30:55.147946Z",
"url": "https://files.pythonhosted.org/packages/fd/e9/9ae1d7ed6f7a45041c68d5dd41b32f330ee51de9325e5028624f25d83534/atlasq-0.15.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "98fe853fce37cdc4c0f13532e34481a66030f2d9c0eecb7b087967a340026714",
"md5": "75cd3452f03f34b1112189db13244f8a",
"sha256": "8bb6ca97ef139b021146c27c3e7e1f264de13a6a1c1b2e444e408a2450ae058b"
},
"downloads": -1,
"filename": "atlasq-0.15.0.tar.gz",
"has_sig": false,
"md5_digest": "75cd3452f03f34b1112189db13244f8a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 39246,
"upload_time": "2024-09-27T14:30:57",
"upload_time_iso_8601": "2024-09-27T14:30:57.345937Z",
"url": "https://files.pythonhosted.org/packages/98/fe/853fce37cdc4c0f13532e34481a66030f2d9c0eecb7b087967a340026714/atlasq-0.15.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-27 14:30:57",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "certego",
"github_project": "atlasq",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "atlasq"
}