Package: atlasq
AtlasQAtlasQ allows the usage ofAtlasSearchkeeping theMongoEnginesyntax.StructureThe package tries to follow the MongoEngine structure;
the major differences reside in thetransform.pyandqueryset.pyfiles.TransformLike in MongoEngine, a step in the pipeline is the creation of a query from aQobject:
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.QuerySetThere are probably a thousand of better implementation, if you actually knew MongoEngine and above allPyMongo.
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 thefiltershould work like anaggregation.
For doing so, and with keeping the compatibility on how MongoEngine works (i.e. the filter should return a queryset ofDocument) we had to do some work.Calling.aggregateinstead has to work as MongoEngine expect, meaning a list of dictionaries.UsageNow the most important part: how do you use this package?frommongoengineimportDocument,fieldsfromatlasqimportAtlasManager,AtlasQ,AtlasQuerySetindex_name=str("my_index")classMyDocument(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")assertisinstance(qs,AtlasQuerySet)obj_from_atlas=qs.first()assertobj==obj_from_atlasobj2_from_atlas=MyDocument.atlas.get(AtlasQ(name="value")&AtlasQ(surname="value2"))assertobj==obj2_from_atlasobj3_from_atlas=MyDocument.atlas.get(AtlasQ(wrong_field="value"))assertobj3_from_atlasisNoneExtended FeaturesValidationWe 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 functionensure_indexon the queryset.frommongoengineimportDocument,fieldsfromatlasqimportAtlasManager,AtlasQindex_name=str("my_index")classMyDocument(Document):name=fields.StringField(required=True)surname=fields.StringField(required=True)atlas=AtlasManager(index_name)result=MyDocument.atlas.ensure_index("user","pwd","group","cluster")assertresultisTrueobj1_from_atlas=MyDocument.atlas.get(AtlasQ(name="value"))obj2_from_atlas=MyDocument.atlas.get(AtlasQ(wrong_field="value"))# raises AtlasIndexFieldErrorEmbeddedDocumentsEmbedded 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 theembeddedDocumentstype, AtlasQ will use theembeddedDocumentquery syntax.
Otherwise, if you used thedocumenttype, or you did not ensure the index, a normaltextsearch with the.syntax will be used.Upload indexIt is possible to upload directly the Search index using AtlasQ, calling the functionupload_indexon the queryset. Syntax checks on the index itself are performed.
If the_idis not present butpkoridwas specified, it will be automatically added, allowing valid text query on the
primary key.frommongoengineimportDocument,fieldsfromatlasqimportAtlasManagerindex_name=str("my_index")index={"analyzer":"lucene.keyword","mappings":{"dynamic":False,"fields":{"_id":{"type":"objectId"},"name":{"type":"string"},"surname":{"type":"string"},}}}classMyDocument(Document):name=fields.StringField(required=True)surname=fields.StringField(required=True)atlas=AtlasManager(index_name)result=MyDocument.atlas.ensure_index("user","pwd","group","cluster")assertresultisFalseMyDocument.atlas.upload_index(index,"user","pwd","group","cluster")result=MyDocument.atlas.ensure_index("user","pwd","group","cluster")assertresultisTrueSortOn the10th of July 2023, theSortfunctionality was released for Atlas search.AtlasQ, from version 0.12.0, will support this feature inside theorder_byfunction.
To have the old behaviour of the order_by (useful if you want to sortafteraggregations and not after the search stage), you can set the kwargas_aggregationasTrue.