-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add: query component, mongo adapter & update tests
- Loading branch information
Showing
5 changed files
with
217 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 48 additions & 0 deletions
48
fai-rag-app/fai-backend/fai_backend/repository/query/component.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
from dataclasses import dataclass | ||
from typing import Literal, Union | ||
|
||
Path = str | ||
|
||
|
||
@dataclass | ||
class AttributeAssignment: | ||
path: Path | ||
value: any | ||
|
||
|
||
@dataclass | ||
class AttributeComparison: | ||
path: Path | ||
operator: Literal['<'] | Literal['<='] | Literal['=='] | Literal['!='] | Literal['>'] | Literal['>='] | ||
value: any | ||
|
||
|
||
@dataclass | ||
class LogicalExpression: | ||
operator: Literal['AND'] | Literal['OR'] = 'AND' | ||
components: list['QueryComponent'] = None | ||
|
||
|
||
QueryComponent = Union[AttributeAssignment, AttributeComparison, LogicalExpression] # noqa: UP007 | ||
|
||
if __name__ == '__main__': | ||
|
||
def evaluate_query(component: QueryComponent): | ||
if isinstance(component, LogicalExpression): | ||
print(f'Evaluate {component.operator} of:') | ||
for sub_component in component.components: | ||
evaluate_query(sub_component) # Recursively handle sub-components | ||
elif isinstance(component, AttributeAssignment): | ||
print(f'Set {component.path} to {component.value}') | ||
elif isinstance(component, AttributeComparison): | ||
print(f'Compare {component.path} {component.operator} with {component.value}') | ||
else: | ||
raise ValueError('Unsupported query component') | ||
|
||
|
||
print('Evaluating query component:') | ||
print('--------------------------') | ||
evaluate_query(LogicalExpression('AND', [ | ||
AttributeComparison('age', '>=', 20), | ||
AttributeComparison('age', '<=', 30) | ||
])) |
60 changes: 60 additions & 0 deletions
60
fai-rag-app/fai-backend/fai_backend/repository/query/mongo.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
from dataclasses import dataclass | ||
|
||
from fai_backend.repository.query import AttributeAssignment, AttributeComparison, LogicalExpression, QueryComponent | ||
|
||
|
||
class QueryAdapter: | ||
def to_mongo_query(self): | ||
raise NotImplementedError('Must implement to_mongo_query') | ||
|
||
|
||
@dataclass | ||
class AttributeAssignmentAdapter(QueryAdapter): | ||
component: AttributeAssignment | ||
|
||
def to_mongo_query(self): | ||
# MongoDB uses $set for updates; for a find query, simple equality is assumed | ||
return {self.component.path: self.component.value} | ||
|
||
|
||
@dataclass | ||
class AttributeComparisonAdapter(QueryAdapter): | ||
component: AttributeComparison | ||
|
||
def to_mongo_query(self): | ||
# MongoDB specific operator map | ||
operator_map = { | ||
'<': '$lt', | ||
'<=': '$lte', | ||
'==': '$eq', | ||
'!=': '$ne', | ||
'>': '$gt', | ||
'>=': '$gte' | ||
} | ||
mongo_operator = operator_map[self.component.operator] | ||
return {self.component.path: {mongo_operator: self.component.value}} | ||
|
||
|
||
@dataclass | ||
class LogicalExpressionAdapter(QueryAdapter): | ||
component: LogicalExpression | ||
|
||
def to_mongo_query(self): | ||
logical_operator_map = { | ||
'AND': '$and', | ||
'OR': '$or' | ||
} | ||
return { | ||
logical_operator_map[self.component.operator]: [adapt_query_component(sub_component).to_mongo_query() for | ||
sub_component in self.component.components]} | ||
|
||
|
||
def adapt_query_component(component: QueryComponent) -> QueryAdapter: | ||
if isinstance(component, AttributeAssignment): | ||
return AttributeAssignmentAdapter(component) | ||
elif isinstance(component, AttributeComparison): | ||
return AttributeComparisonAdapter(component) | ||
elif isinstance(component, LogicalExpression): | ||
return LogicalExpressionAdapter(component) | ||
else: | ||
raise ValueError('Unsupported query component type') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters