Skip to content

Commit a549f3e

Browse files
committed
Show relevant attributes in search results
1 parent f21b877 commit a549f3e

File tree

1 file changed

+31
-14
lines changed

1 file changed

+31
-14
lines changed

lib/luminork-server/src/search/component.rs

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,21 @@ pub async fn search(
5656

5757
/// Component data in search results.
5858
#[derive(Serialize, Deserialize, Debug, ToSchema)]
59+
#[serde(rename_all = "camelCase")]
5960
pub struct ComponentSearchResult {
60-
#[schema(value_type = String, example = "01H9ZQD35JPMBGHH69BT0Q79AA")]
61+
#[schema(example = "01H9ZQD35JPMBGHH69BT0Q79AA", value_type = String)]
6162
pub id: ComponentId,
62-
#[schema(value_type = String, example = "MyInstance")]
63+
#[schema(example = "MyInstance")]
6364
pub name: String,
6465
pub schema: ComponentSearchResultSchema,
66+
pub highlighted_attributes: HashMap<String, serde_json::Value>,
6567
}
6668

6769
/// The schema for a component in search results.
6870
#[derive(Serialize, Deserialize, Debug, ToSchema)]
71+
#[serde(rename_all = "camelCase")]
6972
pub struct ComponentSearchResultSchema {
70-
#[schema(value_type = String, example = "AWS::EC2::Instance")]
73+
#[schema(example = "AWS::EC2::Instance")]
7174
pub name: String,
7275
}
7376

@@ -80,13 +83,15 @@ async fn match_component(
8083
query: Arc<SearchQuery>,
8184
) -> Result<Option<ComponentSearchResult>> {
8285
let attribute_tree = attribute_tree_mv(frigg, workspace_pk, index_ref).await?;
83-
if match_attribute_tree(&attribute_tree, &query) {
86+
let mut highlighted_attributes = HashMap::new();
87+
if match_attribute_tree(&attribute_tree, &query, &mut highlighted_attributes) {
8488
Ok(Some(ComponentSearchResult {
8589
id: attribute_tree.id,
8690
name: attribute_tree.component_name,
8791
schema: ComponentSearchResultSchema {
8892
name: attribute_tree.schema_name,
8993
},
94+
highlighted_attributes,
9095
}))
9196
} else {
9297
Ok(None)
@@ -97,26 +102,38 @@ async fn match_component(
97102
///
98103
/// This is called once for each term in the query, and the results are combined according to
99104
/// query rules (AND, OR, NOT).
100-
fn match_attribute_tree(attribute_tree: &AttributeTreeForSearch, query: &SearchQuery) -> bool {
105+
fn match_attribute_tree(
106+
attribute_tree: &AttributeTreeForSearch,
107+
query: &SearchQuery,
108+
highlighted_attributes: &mut HashMap<String, serde_json::Value>,
109+
) -> bool {
101110
match query {
102111
SearchQuery::MatchValue(term) => {
103112
term.match_str(&attribute_tree.component_name)
104113
|| term.match_str(&attribute_tree.schema_name)
105114
|| term.match_ulid(attribute_tree.id)
106115
}
107-
// TODO support schema:, category:, component: and id:
108-
SearchQuery::MatchAttr { name, terms } => attribute_tree
109-
.attribute_values
110-
.values()
111-
.filter(|av| match_attr_path(&av.path, name))
112-
.any(|av| match_attr_value(&av.value, terms)),
116+
117+
SearchQuery::MatchAttr { name, terms } => {
118+
// TODO support schema:, category:, component: and id:
119+
120+
for av in attribute_tree.attribute_values.values() {
121+
if match_attr_path(&av.path, name) && match_attr_value(&av.value, terms) {
122+
highlighted_attributes.insert(av.path.clone(), av.value.clone());
123+
return true;
124+
}
125+
}
126+
false
127+
}
113128
SearchQuery::And(queries) => queries
114129
.iter()
115-
.all(|query| match_attribute_tree(attribute_tree, query)),
130+
.all(|query| match_attribute_tree(attribute_tree, query, highlighted_attributes)),
116131
SearchQuery::Or(queries) => queries
117132
.iter()
118-
.any(|query| match_attribute_tree(attribute_tree, query)),
119-
SearchQuery::Not(sub_query) => !match_attribute_tree(attribute_tree, sub_query),
133+
.any(|query| match_attribute_tree(attribute_tree, query, highlighted_attributes)),
134+
SearchQuery::Not(sub_query) => {
135+
!match_attribute_tree(attribute_tree, sub_query, highlighted_attributes)
136+
}
120137
SearchQuery::All => true,
121138
}
122139
}

0 commit comments

Comments
 (0)