Skip to content

Commit

Permalink
Add keyword highlight
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaojun207 authored and hengfeiyang committed Jul 4, 2022
1 parent b348291 commit 8e9ad9f
Showing 1 changed file with 77 additions and 7 deletions.
84 changes: 77 additions & 7 deletions web/src/components/search/SearchResult.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,18 @@
</q-td>
<template v-for="col in props.cols" :key="col.name" :props="props">
<q-td v-if="col.name == '@timestamp'" width="238">
{{ col.value }}
<span v-html="col.value"></span>
</q-td>
<q-td v-else>
{{ col.value }}
<span v-html="col.value"></span>
</q-td>
</template>
</q-tr>
<q-tr v-show="props.expand" :props="props">
<q-td colspan="100%">
<pre class="expanded">{{
JSON.stringify(props.row, null, 2)
}}</pre>
<pre class="expanded">
<span v-html="JSON.stringify(props.row, null, 2)"></span>
</pre>
</q-td>
</q-tr>
</template>
Expand Down Expand Up @@ -435,6 +435,67 @@ export default defineComponent({
searchTable.value.setPagination(pagination.value);
};
// eg.1: Gold => ['Gold']
// eg.2: City:Paris => ['Paris']
// eg.3: City:Paris Gold => ['Paris', 'Gold']
// eg.4: City:par* => ['par']
// eg.5: "Paris Gold" => ['Paris Gold']
const getKeywords = (queryString) => {
if (!queryString || queryString.trim().length == 0) {
return [];
}
let arr = [];
// queryString + " " is for special split regular
// split by space, but ignore double quotation marks
const groups = (queryString + " ").split(/ s*(?![^"]*"\ )/);
for (let i = 0; i < groups.length - 1; i++) {
const group = groups[i];
if (!group || group.trim().length == 0) {
continue;
}
// group + ":" is for special split regular
// split by :, but ignore "
const fieldWordArr = (group + ":").split(/:s*(?![^"]*"\:)/);
let keyword = group;
if (fieldWordArr.length > 2) {
keyword = fieldWordArr[1];
}
// delete start and end of * and "
keyword = keyword.replace(/(^\**)|(\**$)/g,"").replace(/(^"*)|("*$)/g,"");
if (keyword.trim().length > 0) {
// make sure key not empty or not space
arr.push(keyword);
}
}
return arr;
};
const highlightResultValue = (value, keywords) => {
if (!value) {
return value;
}
if (typeof value == "string") {
for (const idx in keywords) {
const keyword = keywords[idx];
const highlightText = "<span class='highlight'>" + keyword + "</span>";
value = value.replaceAll(keyword, highlightText);
}
} else if (Array.isArray(value)) {
for (let i = 0; i < value.length; i++) {
value[i] = highlightResultValue(value[i], keywords);
}
} else if (typeof value == "object") {
for (const key in value) {
value[key] = highlightResultValue(value[key], keywords);
}
} else {
// other type direct return value.
}
return value;
};
let lastIndexName = "";
const searchLoading = ref(false);
const searchData = (indexData, queryData) => {
Expand All @@ -448,6 +509,7 @@ export default defineComponent({
indexData.name = "";
}
let keywords = getKeywords(queryData.query);
searchService
.search({ index: indexData.name, query: query })
.then((res) => {
Expand All @@ -461,11 +523,16 @@ export default defineComponent({
results = res.data.hits.hits;
// update index fields
let fields = {};
res.data.hits.hits.forEach((row) => {
results.forEach((row) => {
let keys = Object.deepKeys(row._source);
for (var i in keys) {
for (let i in keys) {
fields[keys[i]] = {};
}
if (keywords && keywords.length > 0) {
// highlight keyword
row._source = highlightResultValue(row._source, keywords);
}
});
emit("updated:fields", Object.keys(fields));
}
Expand Down Expand Up @@ -620,5 +687,8 @@ export default defineComponent({
word-break: break-all;
}
}
.highlight {
background-color: yellow;
}
}
</style>

0 comments on commit 8e9ad9f

Please sign in to comment.