Skip to content

Commit

Permalink
Merge pull request #39 from VianneyMI/38-new-round-of-stages
Browse files Browse the repository at this point in the history
38-new-round-of-stages
  • Loading branch information
VianneyMI committed Jun 18, 2023
2 parents b9e3ec1 + bd402c0 commit 9277ef0
Show file tree
Hide file tree
Showing 42 changed files with 3,472 additions and 82 deletions.
3 changes: 2 additions & 1 deletion monggregate/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ def statement(self)->dict:
def __call__(self)->dict:
"""Makes an instance of any class inheriting from this class callable"""

return self.statement
return self.resolve(self.statement)

class Config(BaseConfig):
"""Base configuration for classes inheriting from this"""

allow_population_by_field_name = True
underscore_attrs_are_private = True
smart_union = True
alias_generator = camelize


Expand Down
1 change: 1 addition & 0 deletions monggregate/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,4 @@ class OperatorEnum(StrEnum):
WEEK = "$week"
YEAR = "$year"
ZIP = "$zip"

191 changes: 186 additions & 5 deletions monggregate/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import Any, Literal
from warnings import warn
from pymongo.database import Database
from pydantic import BaseModel, BaseConfig
from monggregate.base import BaseModel, BaseConfig
from monggregate.stages import (
Stage,
BucketAuto,
Expand All @@ -18,12 +18,18 @@
Project,
ReplaceRoot,
Sample,
Search,
SearchMeta,
Set,
Skip,
SortByCount,
Sort,
Unwind
UnionWith,
Unwind,
Unset
)
from monggregate.stages.search import OperatorLiteral
from monggregate.search.operators.compound import Compound
from monggregate.operators import MergeObjects
from monggregate.expressions.aggregation_variables import ROOT
from monggregate.utils import StrEnum
Expand Down Expand Up @@ -93,6 +99,12 @@ class Pipeline(BaseModel): # pylint: disable=too-many-public-methods
collection : str | None


@property
def statement(self)->list[dict]:
"""Returns the pipeline statement"""

return [stage.statement for stage in self.stages]

class Config(BaseConfig):
"""Configuration Class for Pipeline"""
arbitrary_types_allowed = True
Expand Down Expand Up @@ -659,6 +671,146 @@ def sample(self, value:int)->"Pipeline":
Sample(value=value)
)
return self

def search(
self,
path:str|list[str]=None,
query:str|list[str]=None,
*,
operator_name:OperatorLiteral="text",
index:str="default",
count:dict|None=None,
highlight:dict|None=None,
return_stored_source:bool=False,
score_details:bool=False,
**kwargs:Any
)->"Pipeline":
"""
Adds a search stage to the current pipeline
NOTE : if used, search has to be the first stage of the pipeline
Arguments:
-------------------------------
- path, str|list[str]|None : field to search in
- query, str|list[str]|None : text to search for
- index, str : name of the index to use for the search. Defaults to defaut
- count, dict|None : document that specifies the count options for retrieving
a count of the results
- highlight, dict|None : document that specifies the highlight options for
displaying search terms in their original context
- return_stored_source, bool : Indicates whether to use the copy of the documents
in the Atlas Search index (with just a subset of the fields)
or to return the original full document (slower).
Defaults to False.
True => Use the copy
False => Do a lookup and return the original documents.
- score_details, bool : Indicates whether to retrieve the detailed breakdown of the score for
the documents in the results. Defaults to False.
To view the details, you must use the $meta expression in the
$project stage.
- operator_name, str : Name of the operator to search with. Use the compound operator to run a
compound (i.e query with multiple operators).
- kwargs, Any : Operators specific options.
Includes (non-exhaustive):
- fuzzy, FuzzyOptions (controls fuzzy matching options)
- score, dict (controls scoring options)
- value, numeric|bool|date (for filtering)
- allow_analyzed_field, bool (controls index scanning)
- synonyms
- like, dict|list[dict] (allow looking for similar documents)
"""

self.stages.append(
Search.from_operator(
operator_name=operator_name,
path=path,
query=query,
index=index,
count=count,
highlight=highlight,
return_stored_source=return_stored_source,
score_details=score_details,
**kwargs
)
)


return self

def search_compound(self)->"Compound":
"""Adds a compound search stage"""

self.stages.insert(
0,
Search.compound()
)
return self.stages[0]


def search_meta(
self,
path:str|list[str]=None,
query:str|list[str]=None,
*,
operator_name:OperatorLiteral="text",
index:str="default",
count:dict|None=None,
highlight:dict|None=None,
return_stored_source:bool=False,
score_details:bool=False,
**kwargs:Any
)->"Pipeline":
"""
Adds a searchMeta stage to the current pipeline
NOTE : if used, search has to be the first stage of the pipeline
Arguments:
-------------------------------
- path, str|list[str]|None : field to search in
- query, str|list[str]|None : text to search for
- index, str : name of the index to use for the search. Defaults to defaut
- count, dict|None : document that specifies the count options for retrieving
a count of the results
- highlight, dict|None : document that specifies the highlight options for
displaying search terms in their original context
- return_stored_source, bool : Indicates whether to use the copy of the documents
in the Atlas Search index (with just a subset of the fields)
or to return the original full document (slower).
Defaults to False.
True => Use the copy
False => Do a lookup and return the original documents.
- score_details, bool : Indicates whether to retrieve the detailed breakdown of the score for
the documents in the results. Defaults to False.
To view the details, you must use the $meta expression in the
$project stage.
- operator_name, str : Name of the operator to search with. Use the compound operator to run a
compound (i.e query with multiple operators).
- kwargs, Any : Operators specific options.
Includes (non-exhaustive):
- fuzzy, FuzzyOptions (controls fuzzy matching options)
- score, dict (controls scoring options)
- value, numeric|bool|date (for filtering)
- allow_analyzed_field, bool (controls index scanning)
- synonyms
- like, dict|list[dict] (allow looking for similar documents)
"""

self.stages.append(
SearchMeta.from_operator(
operator_name=operator_name,
path=path,
query=query,
index=index,
count=count,
highlight=highlight,
return_stored_source=return_stored_source,
score_details=score_details,
**kwargs
)
)


return self

def set(self, document:dict={}, **kwargs:Any)->"Pipeline":
"""
Expand Down Expand Up @@ -755,6 +907,23 @@ def sort_by_count(self, by:str)->"Pipeline":
SortByCount(by=by)
)
return self

def union_with(self, collection:str, pipeline:list[dict]|None=None)->"Pipeline":
"""
Adds a union_with stage to the current pipeline.
Arguments:
---------------------------------
- collection / coll, str : The collection or view whose pipeline results you wish to include in the result set
- pipeline, list[dict] | Pipeline | None : An aggregation pipeline to apply to the specified coll.
"""

self.stages.append(
UnionWith(collection=collection, pipeline=pipeline)
)

return self

def unwind(self, path:str, include_array_index:str|None=None, always:bool=False)->"Pipeline":
"""
Expand All @@ -778,10 +947,22 @@ def unwind(self, path:str, include_array_index:str|None=None, always:bool=False)
)
)
return self


def unset(self, field:str=None, fields:list[str]|None=None)->"Pipeline":
"""
Adds an unset stage to the current pipeline.
Arguments:
-------------------------------
- field, str|None: field to be removed
- fields, list[str]|None, list of fields to be removed
"""

self.stages.append(
Unset(field=field, fields=fields)
)

if __name__ == "__main__":
pipeline = Pipeline(stages=[])
pipeline()
return self
1 change: 1 addition & 0 deletions monggregate/search/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Search Package"""
26 changes: 26 additions & 0 deletions monggregate/search/collectors/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""
Subpackage gathering interfaces for Atlas Search collectors.
Collectors return a document representing the metadata results, typically an aggregation over the matching search results.
The Atlas Search aggregation pipeline stage has the following collector:
Collector Description
facet Groups query results by values or ranges in specified, faceted fields and returns the count for each of those groups.
"""

from monggregate.search.collectors.facet import (
# Operator
Facet,
# Results
FacetBucket,
FacetBuckets,
FacetResult,
# Query
StringFacet,
NumericFacet,
DateFacet,
Facets,
# String
FacetName,
)
12 changes: 12 additions & 0 deletions monggregate/search/collectors/collector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"""Collector Module"""

# Standard Library imports
#----------------------------
from abc import ABC

# Package imports
# ---------------------------
from monggregate.base import BaseModel

class SearchCollector(BaseModel, ABC):
"""MongoDB operator abstract base class"""
Loading

0 comments on commit 9277ef0

Please sign in to comment.