Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swap from exact substring matches to each individual word matching #145

Merged
merged 8 commits into from
Jul 21, 2022
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

## dbt-core 1.2.0 (TBD)
- [Snyk] Upgrade prismjs from 1.27.0 to 1.28.0 ([#271](https://github.com/dbt-labs/dbt-docs/issues/271))
- Fixed sample SQL Code for sources when no database is defined ([docs#272](https://github.com/dbt-labs/dbt-docs/pull/272))
Expand All @@ -11,9 +12,11 @@ Contributors:
## dbt-core 1.1.0 (April 28, 2022)
- Fixed capitalization in UI for exposures of `type: ml` ([#256](https://github.com/dbt-labs/dbt-docs/issues/256))
- List packages and tags in alphabetical order ([docs#235](https://github.com/dbt-labs/dbt-docs/pull/235))
- Searches no longer require perfect matches, and instead consider each word individually. `my model` or `model my` will now find `my_model`, without the need for underscores ([docs#143](https://github.com/fishtown-analytics/dbt-docs/issues/143) [docs#145](https://github.com/fishtown-analytics/dbt-docs/pull/145))

Contributors:
- [@pgoslatara](https://github.com/pgoslatara) ([docs#235](https://github.com/dbt-labs/dbt-docs/pull/235))
- [@joellabes](https://github.com/joellabes) ([docs#145](https://github.com/dbt-labs/dbt-docs/pull/145))

## dbt-core 1.0.4 (March 18th, 2022)

Expand Down Expand Up @@ -72,6 +75,7 @@ Contributors:
Contributors:
- [@Mr-Nobody99](https://github.com/Mr-Nobody99) ([docs#138](https://github.com/fishtown-analytics/dbt-docs/pull/138))
- [@jplynch77](https://github.com/jplynch77) ([docs#139](https://github.com/fishtown-analytics/dbt-docs/pull/139))
- [@joellabes](https://github.com/joellabes) ([docs#145](https://github.com/fishtown-analytics/dbt-docs/pull/145))

## dbt 0.18.1 (October 13, 2020)
- Add Exposure nodes ([docs#135](https://github.com/fishtown-analytics/dbt-docs/issues/135), [docs#136](https://github.com/fishtown-analytics/dbt-docs/pull/136), [docs#137](https://github.com/fishtown-analytics/dbt-docs/pull/137))
Expand Down
33 changes: 26 additions & 7 deletions src/app/components/search/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,14 @@ angular
});

scope.shorten = function(text) {
if(text != null && text.length > 0){
if(text != null && text.trim().length > 0 && scope.query != null && scope.query.trim().length > 0){
let modified = text.replace(/\s+/g, ' ');
let indexOfInstance = modified.search(scope.query);
let startIndex = (indexOfInstance - 75) < 0? 0: indexOfInstance - 75;
let endIndex = (indexOfInstance + 75) > modified.length? modified.length: indexOfInstance + 75;
//choose the first word in the search as the anchor for shortening.
//Escaping in case the first token is "*" or another reserved regex character
let first_token = escapeRegExp(getQueryTokens(scope.query)[0]);
let indexOfInstance = modified.search(new RegExp(first_token));
let startIndex = (indexOfInstance - 75) < 0 ? 0 : indexOfInstance - 75;
let endIndex = (indexOfInstance + 75) > modified.length ? modified.length : indexOfInstance + 75;
let shortened = "..." + modified.substring(startIndex, endIndex) + "...";
return shortened;
}
Expand All @@ -101,7 +104,12 @@ angular
if (!scope.query || !text) {
return $sce.trustAsHtml(text);
}
return $sce.trustAsHtml(text.replace(new RegExp(scope.query, 'gi'), '<span class="search-result-match">$&</span>'));
//wrap each word in a capturing group with a pipe between them, to allow any of the matches to highlight
//e.g. "hello WORLD" changes to "(hello)|(world)"
let query_segments = getQueryTokens(scope.query);
let escaped_segments = query_segments.map(segment => escapeRegExp(segment));
let highlight_words = "(" + escaped_segments.join(")|(") + ")";
return $sce.trustAsHtml(text.replace(new RegExp(highlight_words, 'gi'), '<span class="search-result-match">$&</span>'));
}

scope.$watch("query", function(nv, ov) {
Expand All @@ -113,16 +121,27 @@ angular

scope.columnFilter = function(columns) {
var matches = [];
let query_segments = getQueryTokens(scope.query);

for (var column in columns) {
if (column.toLowerCase().indexOf(scope.query.toLowerCase()) != -1) {
if (query_segments.every(segment => column.toLowerCase().indexOf(segment) != -1)) {
matches.push(column);
}
}
return matches;
}

scope.limitColumns = function(id) {
return scope.limit_columns[id] !== undefined? scope.limit_columns[id] : 3;
return scope.limit_columns[id] !== undefined ? scope.limit_columns[id] : 3;
}

//from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
function escapeRegExp(string) {
return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}

function getQueryTokens(query){
return _.words(query.toLowerCase());
}
}
}
Expand Down
1 change: 0 additions & 1 deletion src/app/main/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ angular
});

$scope.onSearchKeypress = function(e) {
console.log(e);
if (e.key == 'Escape') {
$scope.clearSearch();
e.preventDefault();
Expand Down
19 changes: 10 additions & 9 deletions src/app/services/project_service.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ angular
});
}

function fuzzySearchObj(val, obj) {
function fuzzySearchObj(query, obj) {
var objects = [];
var search_keys = {
'name':'string',
Expand All @@ -265,29 +265,30 @@ angular
'arguments': 'array',
'label': 'string',
};
var search = new RegExp(val, "i")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was never used



let query_segments = _.words(query.toLowerCase());

for (var i in search_keys) {
if (!obj[i]) {
continue;
} else if (search_keys[i] === 'string' && obj[i].toLowerCase().indexOf(val.toLowerCase()) != -1) {
objects.push({key: i, value: val});
} else if (search_keys[i] === 'string' && query_segments.every(segment => obj[i].toLowerCase().indexOf(segment) != -1)) {
objects.push({key: i, value: query});
} else if (search_keys[i] === 'object') {
for (var column_name in obj[i]) {
// there a spark bug where columns are missign from the catalog. That needs to be fixed
// outside of docs but this if != null check will allow docs to continue to function now
// and also when the bug is fixed.
// relevant issue: https://github.com/dbt-labs/dbt-spark/issues/295
if (obj[i][column_name]["name"] != null) {
if (obj[i][column_name]["name"].toLowerCase().indexOf(val.toLowerCase()) != -1) {
objects.push({key: i, value: val});
if (query_segments.every(segment => obj[i][column_name]["name"].toLowerCase().indexOf(segment) != -1)) {
objects.push({key: i, value: query});
}
}
}
} else if (search_keys[i] === 'array') {
for (var tag of obj[i]) {
if (JSON.stringify(tag).toLowerCase().indexOf(val.toLowerCase()) != -1) {
objects.push({key: i, value: val});
if (query_segments.every(segment => JSON.stringify(tag).toLowerCase().indexOf(segment) != -1)) {
objects.push({key: i, value: query});
}
}
}
Expand Down