Skip to content

Commit

Permalink
fix(backend): 全站搜索优化 TencentBlueKing#8587
Browse files Browse the repository at this point in the history
# Reviewed, transaction id: 26720
  • Loading branch information
ygcyao committed Dec 13, 2024
1 parent 3190702 commit c57bf85
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 36 deletions.
4 changes: 2 additions & 2 deletions dbm-ui/backend/db_services/quick_search/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@


class ResourceType(str, StructuredEnum):
CLUSTER_NAME = EnumField("cluster_name", _("集群名"))
CLUSTER_DOMAIN = EnumField("cluster_domain", _("集群域名"))
# CLUSTER_NAME = EnumField("cluster_name", _("集群名"))
entry = EnumField("entry", _("访问入口"))
INSTANCE = EnumField("instance", _("实例"))
TICKET = EnumField("ticket", _("单号"))
TASK = EnumField("task", _("任务"))
Expand Down
78 changes: 60 additions & 18 deletions dbm-ui/backend/db_services/quick_search/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
from django.db.models.functions import Concat
from django.forms import model_to_dict

from backend.configuration.models import DBAdministrator
from backend.db_meta.enums import ClusterType
from backend.db_meta.models import Cluster, Machine, ProxyInstance, StorageInstance
from backend.db_meta.models import Cluster, ClusterEntry, Machine, ProxyInstance, StorageInstance
from backend.db_services.dbresource.handlers import ResourceHandler
from backend.db_services.quick_search import constants
from backend.db_services.quick_search.constants import FilterType, ResourceType
Expand Down Expand Up @@ -134,17 +135,56 @@ def common_filter(self, objs, return_type="list", fields=None, limit=None):
limit = limit or self.limit
return list(objs[:limit].values(*fields))

def supplementary_fields(self, objects_list: list):
"""补充 主dba和db类型字段"""
for object in objects_list:
# 将 db_type 补充到对象中
object["db_type"] = ClusterType.cluster_type_to_db_type(object["cluster_type"])

# 获取dba人员 # DBA 人员获取优先级: 业务 > 平台 > 默认空值
dba_list = DBAdministrator.list_biz_admins(bk_biz_id=object["bk_biz_id"])
dba_content = next((dba for dba in dba_list if dba["db_type"] == object["db_type"]))
object["dba"] = dba_content["users"][0] if dba_content["users"] else None
object["is_show_dba"] = dba_content["is_show"]
return objects_list

def filter_cluster_name(self, keyword_list: list):
"""过滤集群名"""
qs = self.generate_filter_for_str("name", keyword_list)
objs = Cluster.objects.filter(qs)
return self.common_filter(objs)

def filter_cluster_domain(self, keyword_list: list):
"""过滤集群域名"""
qs = self.generate_filter_for_domain("immute_domain", keyword_list)
objs = Cluster.objects.filter(qs)
return self.common_filter(objs)
def filter_entry(self, keyword_list: list):
"""过滤集群访问入口"""
qs = self.generate_filter_for_domain("entry", keyword_list)

if self.bk_biz_ids:
qs = Q(bk_biz_id__in=self.bk_biz_ids) & qs

if self.db_types:
qs = Q(cluster_type__in=self.cluster_types) & qs

common_fields = {
"cluster_type": F("cluster__cluster_type"),
"immute_domain": F("cluster__immute_domain"),
"bk_biz_id": F("cluster__bk_biz_id"),
"cluster_status": F("cluster__status"),
}
fields = [
"id",
"cluster_entry_type",
"entry",
"cluster_id",
"role",
*common_fields.keys(),
]
objs = (
ClusterEntry.objects.filter(qs)
.select_related("cluster")
.annotate(**common_fields)
.values(*fields)[: self.limit]
)
return self.supplementary_fields(list(objs))

def filter_instance(self, keyword_list: list):
"""过滤实例"""
Expand All @@ -168,17 +208,6 @@ def filter_instance(self, keyword_list: list):
"bk_idc_name": F("machine__bk_idc_name"),
"ip_port": Concat("machine__ip", Value(":"), "port", output_field=CharField()),
}

storage_objs = (
StorageInstance.objects.prefetch_related("cluster", "machine")
.annotate(role=F("instance_role"), **common_fields)
.filter(qs)
)
proxy_objs = (
ProxyInstance.objects.prefetch_related("cluster", "machine")
.annotate(role=F("access_layer"), **common_fields)
.filter(qs)
)
fields = [
"id",
"name",
Expand All @@ -192,7 +221,20 @@ def filter_instance(self, keyword_list: list):
"phase",
*common_fields.keys(),
]
return list(storage_objs[: self.limit].values(*fields)) + list(proxy_objs[: self.limit].values(*fields))
storage_objs = (
StorageInstance.objects.prefetch_related("cluster", "machine")
.annotate(role=F("instance_role"), **common_fields)
.filter(qs)
.values(*fields)[: self.limit]
)
proxy_objs = (
ProxyInstance.objects.prefetch_related("cluster", "machine")
.annotate(role=F("access_layer"), **common_fields)
.filter(qs)
.values(*fields)[: self.limit]
)

return self.supplementary_fields(list(storage_objs) + list(proxy_objs))

def filter_task(self, keyword_list: list):
"""过滤任务"""
Expand Down
2 changes: 2 additions & 0 deletions dbm-ui/backend/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ def init_storage_instance():
machine=machine,
bk_biz_id=constant.BK_BIZ_ID,
name=constant.INSTANCE_NAME,
cluster_type=ClusterType.TenDBHA.value,
)
storage_instance.cluster.add(cluster)
yield storage_instance
Expand All @@ -181,6 +182,7 @@ def init_proxy_instance():
machine=machine,
bk_biz_id=constant.BK_BIZ_ID,
name=constant.INSTANCE_NAME,
cluster_type=ClusterType.TenDBHA.value,
)
proxy_instance.cluster.add(cluster)
yield proxy_instance
Expand Down
37 changes: 21 additions & 16 deletions dbm-ui/backend/tests/db_services/quick_search/test_quick_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import pytest

from backend.components.dbresource.client import DBResourceApi
from backend.db_meta.enums import ClusterEntryRole
from backend.db_services.quick_search.views import QuickSearchViewSet
from backend.utils.pytest import AuthorizedAPIRequestFactory

Expand Down Expand Up @@ -52,31 +53,35 @@ def _request_quick_search(self, resource_list_mock, query):
response = quick_search_viewset(request)
return response

@pytest.mark.parametrize("query", [QUICK_SEARCH_CONTAINS_PARAMS, QUICK_SEARCH_EXACT_PARAMS])
@patch.object(DBResourceApi, "resource_list")
def test_quick_search_for_cluster_name(self, resource_list_mock, query, init_cluster):
"""
测试搜索集群名称
"""
target_value = init_cluster.name
query["keyword"] = self._get_keyword(query, target_value)
response = self._request_quick_search(resource_list_mock, query)
assert response.status_code == 200
result = [cluster.get("id") for cluster in response.data.get("cluster_name")]
assert init_cluster.id in result
# @pytest.mark.parametrize("query", [QUICK_SEARCH_CONTAINS_PARAMS, QUICK_SEARCH_EXACT_PARAMS])
# @patch.object(DBResourceApi, "resource_list")
# def test_quick_search_for_cluster_name(self, resource_list_mock, query, init_cluster):
# """
# 测试搜索集群名称
# """
# target_value = init_cluster.name
# query["keyword"] = self._get_keyword(query, target_value)
# response = self._request_quick_search(resource_list_mock, query)
# assert response.status_code == 200
# result = [cluster.get("id") for cluster in response.data.get("cluster_name")]
# assert init_cluster.id in result

@pytest.mark.parametrize("query", [QUICK_SEARCH_CONTAINS_PARAMS, QUICK_SEARCH_EXACT_PARAMS])
@patch.object(DBResourceApi, "resource_list")
def test_quick_search_for_cluster_domain(self, resource_list_mock, query, init_cluster):
def test_quick_search_for_entry(self, resource_list_mock, query, init_cluster):
"""
测试搜索集群域名
测试搜索访问入口
"""
target_value = init_cluster.immute_domain
query["keyword"] = self._get_keyword(query, target_value)
response = self._request_quick_search(resource_list_mock, query)
assert response.status_code == 200
result = [cluster.get("id") for cluster in response.data.get("cluster_domain")]
assert init_cluster.id in result
result = [
entry.get("entry")
for entry in response.data.get("entry")
if entry["role"] == ClusterEntryRole.MASTER_ENTRY
]
assert init_cluster.immute_domain in result

@pytest.mark.parametrize("query", [QUICK_SEARCH_CONTAINS_PARAMS, QUICK_SEARCH_EXACT_PARAMS])
@patch.object(DBResourceApi, "resource_list")
Expand Down

0 comments on commit c57bf85

Please sign in to comment.