Fully functional fulltext search

This commit is contained in:
2023-01-25 14:59:23 +01:00
parent 893013cdae
commit a2c930d457
6 changed files with 172 additions and 81 deletions

View File

@@ -1,18 +1,10 @@
from beanie import PydanticObjectId
from beanie.odm.enums import SortDirection
from beanie.operators import And, Or, RegEx, Eq
from fastapi import APIRouter, HTTPException
from fastapi_paginate import Page, Params, add_pagination
from fastapi_paginate.ext.motor import paginate
from typing import TypeVar, List, Generic, Any, Dict
T = TypeVar('T')
U = TypeVar('U')
V = TypeVar('V')
W = TypeVar('W')
def parse_sort(sort_by):
if not sort_by:
@@ -26,8 +18,29 @@ def parse_sort(sort_by):
return fields
def parse_query(query) -> Dict[Any, Any]:
return {}
def parse_query(query: str, model):
if query is None:
return {}
and_array = []
for criterion in query.split(' AND '):
[column, operator, value] = criterion.split(' ', 2)
column = column.lower()
if column == 'fulltext':
if not model.Settings.fulltext_search:
continue
or_array = []
for field in model.Settings.fulltext_search:
or_array.append(RegEx(field, value, 'i'))
operand = Or(or_array) if len(or_array) > 1 else or_array[0]
elif operator == 'eq':
operand = Eq(column, value)
and_array.append(operand)
return And(and_array) if len(and_array) > 1 else and_array[0]
def get_crud_router(model, model_create, model_read, model_update):
@@ -48,8 +61,7 @@ def get_crud_router(model, model_create, model_read, model_update):
@router.get("/", response_model=Page[model_read], response_description="{} records retrieved".format(model.__name__))
async def read_list(size: int = 50, page: int = 1, sort_by: str = None, query: str = None) -> Page[model_read]:
sort = parse_sort(sort_by)
query = parse_query(query)
# limit=limit, skip=offset,
query = parse_query(query, model_read)
collection = model.get_motor_collection()
items = paginate(collection, query, Params(**{'size': size, 'page': page}), sort=sort)
@@ -89,5 +101,3 @@ def get_crud_router(model, model_create, model_read, model_update):
add_pagination(router)
return router