add: detailed search

v0.2
rrr-marble 4 years ago
parent 2ef6b3227d
commit 7aa5b423e5

@ -42,6 +42,38 @@ def get_item_by_description(db: Session, needle: str, skip: int = 0, limit: int
return result return result
def get_item_by_detailed_description(
db: Session, query: schemas.DetailedSearchQuery, skip: int = 0, limit: int = 20
):
"""фильтры для поиска Описаний наборов данных по атрибутам
дополнительный возможный синтаксис основного запроса преобразуется
в поисковый запрос содержащий:
- простой текст: переданные слова в любом порядке
- "текст в кавычках": переданные слова в указанном порядке
- OR: какие-либо из переданных слов
- -: не содержащий данного слова
дополнительные поля ипользуются напрямую
"""
# hardcode russian for now
# built-in postgress websearch_to_tsquery() is good
# https://www.postgresql.org/docs/11/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES
# TODO: add requested search columns [0]
items_table = inspect(models.Item).local_table
result = db.query(models.Item)
# filter with the main query (if present)
if query.main_query is not None:
result = result.filter(
items_table.c.geodata_search_ts.op("@@")(
func.websearch_to_tsquery('"russian"', main_query)
)
)
# filter by additionalfields (if present)
result = result.filter_by(**query.dict(exclude={"main_query"}, exclude_none=True))
return result.order_by(items_table.c.id).offset(skip).limit(limit).all()
def get_items(db: Session, skip: int = 0, limit: int = 20): def get_items(db: Session, skip: int = 0, limit: int = 20):
"""список доступных в системе Описаний наборов данных""" """список доступных в системе Описаний наборов данных"""
return db.query(models.Item).offset(skip).limit(limit).all() return db.query(models.Item).offset(skip).limit(limit).all()

@ -130,7 +130,7 @@ def read_items(
@app.get( @app.get(
"/search/", "/search/",
response_model=List[schemas.Item], response_model=List[schemas.Item],
responses={400: {"description": "Запрос слишком короткий (минимумл 3 символа)"}}, responses={400: {"description": "Запрос слишком короткий (минимум 3 символа)"}},
) )
def search(q: str, skip: int = 0, limit: int = 20, db: Session = Depends(get_db)): def search(q: str, skip: int = 0, limit: int = 20, db: Session = Depends(get_db)):
"""фильтры для поиска Описаний наборов данных по атрибутам """фильтры для поиска Описаний наборов данных по атрибутам
@ -149,6 +149,36 @@ def search(q: str, skip: int = 0, limit: int = 20, db: Session = Depends(get_db)
return crud.get_item_by_description(db=db, needle=q, skip=skip, limit=limit) return crud.get_item_by_description(db=db, needle=q, skip=skip, limit=limit)
@app.post(
"/detailed_search/",
response_model=List[schemas.Item],
)
def detailed_search(
query: schemas.DetailedSearchQuery,
skip: int = 0,
limit: int = 20,
db: Session = Depends(get_db),
):
"""фильтры для поиска Описаний наборов данных по атрибутам
дополнительный возможный синтаксис в запросах преобразуется
в поисковый запрос содержащий:
- простой текст: переданные слова в любом порядке
- "текст в кавычках": переданные слова в указанном порядке
- OR ИЛИ: какие-либо из переданных слов
- -: не содержащий данного слова
дополнительные поля ипользуются напрямую
"""
if query.main_query is not None:
# replace all full ИЛИ words with OR
query.main_query = substitute(
r"\bИЛИ\b", "OR", query.main_query, flags=IGNORECASE
)
return crud.get_item_by_detailed_description(
db=db, query=query, skip=skip, limit=limit
)
@app.get("/headers/", response_model=List[schemas.Header]) @app.get("/headers/", response_model=List[schemas.Header])
def read_headers(db: Session = Depends(get_db)): def read_headers(db: Session = Depends(get_db)):
"""полные наименования столбцов таблиц""" """полные наименования столбцов таблиц"""

@ -69,3 +69,32 @@ class InsertStatus(BaseModel):
accepted: int accepted: int
processed: int processed: int
process_time: timedelta process_time: timedelta
class DetailedSearchQuery(BaseModel):
"""detailed search query format"""
main_query: Optional[str] = None
fadr: Optional[str] = None
internal_id: Optional[str] = None
x_coord: Optional[str] = None
y_coord: Optional[str] = None
gis_category: Optional[str] = None
category: Optional[str] = None
basin: Optional[str] = None
deposit: Optional[str] = None
well: Optional[str] = None
depth: Optional[str] = None
stratum: Optional[str] = None
owner: Optional[str] = None
org: Optional[str] = None
ownercontacts: Optional[str] = None
samplelist: Optional[str] = None
description: Optional[str] = None
form_dimentions: Optional[str] = None
datalist: Optional[str] = None
resolution: Optional[str] = None
date: Optional[str] = None
additional_info: Optional[str] = None
scanner: Optional[str] = None
comment: Optional[str] = None

Loading…
Cancel
Save