Commit b83f9794 authored by fabian serin's avatar fabian serin
Browse files

Merge branch 'fserin/search_curves_by_wellbore' into 'master'

Search WellLogs by Curve name

See merge request !221
parents 60250cea e60eb78d
Pipeline #61318 passed with stages
in 6 minutes and 10 seconds
......@@ -126,14 +126,22 @@ async def query_request_with_specific_attribute(query_type: str, attribute: str,
query_request=query_request)
def update_query_with_names_based_search(names: str = None, user_query: str = None, name_field = "data.FacilityName") -> str:
def update_query_with_names_based_search(names: str = None, user_query: str = None,
name_field: str = "data.FacilityName") -> str:
if names is None:
return user_query
generated_query = f"{name_field}:{names}"
return added_query(generated_query, user_query)
def update_query_with_nested_names_based_search(array_field: str, nested_field: str, names: str = None,
user_query: str = None) -> str:
if names is None:
return user_query
generated_query = f"(nested({array_field}, ({nested_field}:({names}))))"
return added_query(generated_query, user_query)
def escape_forbidden_characters_for_search(input_str: str) -> str:
# Reserved character are listed here https://community.opengroup.org/osdu/documentation/-/blob/master/platform/tutorials/core-services/SearchService.md
# ? and * are allowed for wildcard search
......
......@@ -14,6 +14,7 @@
from fastapi import APIRouter, Depends
from odes_search.models import CursorQueryResponse
from app.utils import Context
from .search_v3 import (
SearchQueryRequest,
......@@ -27,7 +28,8 @@ from .search_v3 import (
added_relationships_query,
WELLBORE_RELATIONSHIP,
get_ctx,
query_type)
query_type,
update_query_with_nested_names_based_search)
from ..common_parameters import REQUIRED_ROLES_READ
router = APIRouter()
......@@ -57,14 +59,18 @@ async def query_trajectories_bywellbore(wellboreId: str, body: SearchQueryReques
@router.post('/query/welllogs',
summary='Query with cursor, search WellLogs by name and optionally by wellbore ID',
description=f"""Get all WellLogs objects using its name and optionally relationship Wellbore ID.
summary='Query with cursor, search WellLogs by name and optionally by wellbore ID and curves mnemonics',
description=f"""Get all WellLogs objects using its name and optionally relationship Wellbore ID. Filtering can be done on curves mnemonics
<p>The WellLogs kind is {OSDU_WELLLOG_KIND} returns all records directly based on existing schemas. The query is done on data.Name field</p>{REQUIRED_ROLES_READ}""",
response_model=CursorQueryResponse)
async def query_welllogs_by_name(names: str = None, wellbore_id: str = None, body: SearchQueryRequest = DEFAULT_QUERYREQUEST,
ctx: Context = Depends(get_ctx)):
async def query_welllogs_by_name(names: str = None, wellbore_id: str = None, mnemonics: str = None,
body: SearchQueryRequest = DEFAULT_QUERYREQUEST,
ctx: Context = Depends(get_ctx)):
if wellbore_id is not None:
body.query = added_relationships_query(wellbore_id, WELLBORE_RELATIONSHIP, body.query)
names = escape_forbidden_characters_for_search(names)
mnemonics = escape_forbidden_characters_for_search(mnemonics)
body.query = update_query_with_names_based_search(names=names, user_query=body.query, name_field="data.Name")
body.query = update_query_with_nested_names_based_search(array_field='data.Curves', nested_field='Mnemonic',
names=mnemonics, user_query=body.query)
return await query_request(query_type, OSDU_WELLLOG_KIND, ctx, body)
......@@ -9356,7 +9356,7 @@
},
"/alpha/ddms/v3/query/welllogs": {
"post": {
"description": "Get all WellLogs objects using its name and optionally relationship Wellbore ID. \n <p>The WellLogs kind is *:wks:work-product-component--WellLog:* returns all records directly based on existing schemas. The query is done on data.Name field</p>\n<p>Required roles: 'users.datalake.viewers' or 'users.datalake.editors' or 'users.datalake.admins'.\n\"In addition, users must be a member of data groups to access the data.</p>\n",
"description": "Get all WellLogs objects using its name and optionally relationship Wellbore ID. Filtering can be done on curves mnemonics\n <p>The WellLogs kind is *:wks:work-product-component--WellLog:* returns all records directly based on existing schemas. The query is done on data.Name field</p>\n<p>Required roles: 'users.datalake.viewers' or 'users.datalake.editors' or 'users.datalake.admins'.\n\"In addition, users must be a member of data groups to access the data.</p>\n",
"operationId": "query_welllogs_by_name_alpha_ddms_v3_query_welllogs_post",
"parameters": [
{
......@@ -9377,6 +9377,15 @@
"type": "string"
}
},
{
"in": "query",
"name": "mnemonics",
"required": false,
"schema": {
"title": "Mnemonics",
"type": "string"
}
},
{
"description": "identifier of the data partition to query",
"in": "header",
......@@ -9432,7 +9441,7 @@
"HTTPBearer": []
}
],
"summary": "Query with cursor, search WellLogs by name and optionally by wellbore ID",
"summary": "Query with cursor, search WellLogs by name and optionally by wellbore ID and curves mnemonics",
"tags": [
"ALPHA feature: search v3"
]
......
......@@ -397,6 +397,22 @@ def build_request_search_welllog_by_name() -> RequestRunner:
return RequestRunner(rq_proto)
def build_request_search_welllog_by_curve_mnemonics() -> RequestRunner:
rq_proto = Request(
name='search wellbore by name',
method='POST',
url='{{base_url}}/alpha/ddms/v3/{{search_query_type}}/welllogs?mnemonics=Example%20Mnemonic',
headers={
'accept': 'application/json',
'data-partition-id': '{{data_partition}}',
'Connection': '{{header_connection}}',
'Authorization': 'Bearer {{token}}',
},
payload='{}'
)
return RequestRunner(rq_proto)
def build_request_search_welllog_by_name_and_wellbore() -> RequestRunner:
rq_proto = Request(
......
......@@ -126,6 +126,16 @@ def test_search_wellLog_by_name(with_wdms_env):
assert resobj.totalCount >= 1
@pytest.mark.tag('search')
@pytest.mark.dependency(depends=["test_setup_for_search"])
def test_search_wellLog_by_curve_mnemonics(with_wdms_env):
#Only search and no fast search
env = with_wdms_env
env.set('search_query_type', 'query')
resobj = build_request_search_welllog_by_curve_mnemonics().call(with_wdms_env, assert_status=200).get_response_obj()
assert resobj.totalCount >= 1
@pytest.mark.tag('search')
@pytest.mark.dependency(depends=["test_setup_for_search"])
def test_search_wellLog_by_name_and_wellbore(with_wdms_env):
......
......@@ -45,6 +45,20 @@ def test_update_query_with_names_based_search(names, user_query, expected_query)
assert search_v3.update_query_with_names_based_search(names, user_query) == expected_query
NESTED_NAMES_QUERY_PARAMS = [
(None, None, None, None, None),
('array.field', 'nested_field', 'names', 'user_query', '(nested(array.field, (nested_field:(names)))) AND (user_query)'),
('array.field', 'nested_field', None, 'user query', 'user query'),
]
@pytest.mark.parametrize("array_field, nested_field, names, user_query, expected_query", NESTED_NAMES_QUERY_PARAMS)
def test_update_query_with_neted_names_based_search(array_field, nested_field, names, user_query, expected_query):
assert search_v3.update_query_with_nested_names_based_search(array_field, nested_field, names,
user_query) == expected_query
ESCAPE_CHAR_PARAMS = [
('', ''),
('not char to escape', 'not char to escape'),
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment