Source code for langchain_azure_ai.query_constructors.cosmosdb_no_sql

"""Translator that converts a StructuredQuery into a CosmosDB NoSQL query."""

from typing import Any, Dict, Tuple

from langchain_core.structured_query import (
    Comparator,
    Comparison,
    Operation,
    Operator,
    StructuredQuery,
    Visitor,
)

SQL_COMPARATOR = {
    Comparator.EQ: "=",
    Comparator.NE: "!=",
    Comparator.GT: ">",
    Comparator.GTE: ">=",
    Comparator.LT: "<",
    Comparator.LTE: "<=",
    Comparator.LIKE: "LIKE",
    Comparator.IN: "IN",
    Comparator.NIN: "NOT IN",
}

SQL_OPERATOR = {
    Operator.AND: "AND",
    Operator.OR: "OR",
    Operator.NOT: "NOT",
}


[docs] class AzureCosmosDbNoSQLTranslator(Visitor): """A visitor that converts a StructuredQuery into an CosmosDB NO SQL query."""
[docs] def __init__(self, table_name: str = "c") -> None: """Initialize the translator with the table name.""" self.table_name = table_name
[docs] def visit_comparison(self, comparison: Comparison) -> str: """Visit a comparison operation and convert it into an SQL condition.""" operator = SQL_COMPARATOR.get(comparison.comparator) value = comparison.value field = f"{self.table_name}.{comparison.attribute}" if operator is None: raise ValueError(f"Unsupported operator: {comparison.comparator}") # Correct value formatting if isinstance(value, str): value = f"'{value}'" elif isinstance(value, (list, tuple)): # Handle IN clause if comparison.comparator not in [Comparator.IN, Comparator.NIN]: raise ValueError( f"Invalid comparator for list value: {comparison.comparator}" ) value = ( "(" + ", ".join(f"'{v}'" if isinstance(v, str) else str(v) for v in value) + ")" ) return f"{field} {operator} {value}"
[docs] def visit_operation(self, operation: Operation) -> str: """Visit logical operations and convert them into SQL expressions. Uses parentheses to ensure correct precedence. """ operator = SQL_OPERATOR.get(operation.operator) if operator is None: raise ValueError(f"Unsupported operator: {operation.operator}") expressions = [arg.accept(self) for arg in operation.arguments] if operation.operator == Operator.NOT: return f"NOT ({expressions[0]})" return f"({f' {operator} '.join(expressions)})"
[docs] def visit_structured_query( self, structured_query: StructuredQuery ) -> Tuple[str, Dict[str, Any]]: """Visit a structured query and convert it into parameter for vectorstore.""" if structured_query.filter is None: kwargs = {} else: kwargs = {"where": structured_query.filter.accept(self)} return structured_query.query, kwargs