|
|
@@ -15,6 +15,7 @@ import PrivateLegacyPagesDelegator from './search-delegator/private-legacy-pages
|
|
|
|
|
|
import { PageModel } from '../models/page';
|
|
|
import { serializeUserSecurely } from '../models/serializers/user-serializer';
|
|
|
+import { nqStringRegExp, parseNQString } from '~/utils/named-query';
|
|
|
|
|
|
// eslint-disable-next-line no-unused-vars
|
|
|
const logger = loggerFactory('growi:service:search');
|
|
|
@@ -47,7 +48,7 @@ class SearchService implements SearchQueryParser, SearchResolver {
|
|
|
|
|
|
isErrorOccuredOnSearching: boolean | null
|
|
|
|
|
|
- fullTextSearchDelegator: any & SearchDelegator
|
|
|
+ fullTextSearchDelegator: any & ElasticsearchDelegator
|
|
|
|
|
|
nqDelegators: {[key in SearchDelegatorName]: SearchDelegator}
|
|
|
|
|
|
@@ -97,10 +98,10 @@ class SearchService implements SearchQueryParser, SearchResolver {
|
|
|
logger.info('No elasticsearch URI is specified so that full text search is disabled.');
|
|
|
}
|
|
|
|
|
|
- generateNQDelegators(defaultDelegator: SearchDelegator): {[key in SearchDelegatorName]: SearchDelegator} {
|
|
|
+ generateNQDelegators(defaultDelegator: ElasticsearchDelegator): {[key in SearchDelegatorName]: SearchDelegator} {
|
|
|
return {
|
|
|
[SearchDelegatorName.DEFAULT]: defaultDelegator,
|
|
|
- [SearchDelegatorName.PRIVATE_LEGACY_PAGES]: new PrivateLegacyPagesDelegator(),
|
|
|
+ [SearchDelegatorName.PRIVATE_LEGACY_PAGES]: new PrivateLegacyPagesDelegator() as SearchDelegator,
|
|
|
};
|
|
|
}
|
|
|
|
|
|
@@ -192,18 +193,15 @@ class SearchService implements SearchQueryParser, SearchResolver {
|
|
|
}
|
|
|
|
|
|
async parseSearchQuery(_queryString: string): Promise<ParsedQuery> {
|
|
|
- const regexp = new RegExp(/^\[nq:.+\]$/g); // https://regex101.com/r/FzDUvT/1
|
|
|
- const replaceRegexp = new RegExp(/\[nq:|\]/g);
|
|
|
-
|
|
|
const queryString = normalizeQueryString(_queryString);
|
|
|
|
|
|
// when Normal Query
|
|
|
- if (!regexp.test(queryString)) {
|
|
|
+ if (!nqStringRegExp.test(queryString)) {
|
|
|
return { queryString, terms: this.parseQueryString(queryString) };
|
|
|
}
|
|
|
|
|
|
// when Named Query
|
|
|
- const name = queryString.replace(replaceRegexp, '');
|
|
|
+ const name = parseNQString(queryString);
|
|
|
const nq = await NamedQuery.findOne({ name });
|
|
|
|
|
|
// will delegate to full-text search
|
|
|
@@ -224,24 +222,19 @@ class SearchService implements SearchQueryParser, SearchResolver {
|
|
|
return parsedQuery;
|
|
|
}
|
|
|
|
|
|
- async resolve(parsedQuery: ParsedQuery): Promise<[SearchDelegator, SearchableData | null]> {
|
|
|
- const { queryString, terms, delegatorName } = parsedQuery;
|
|
|
- if (delegatorName != null) {
|
|
|
- const nqDelegator = this.nqDelegators[delegatorName];
|
|
|
- if (nqDelegator != null) {
|
|
|
- return [nqDelegator, null];
|
|
|
- }
|
|
|
- }
|
|
|
+ async resolve(parsedQuery: ParsedQuery): Promise<[SearchDelegator, SearchableData]> {
|
|
|
+ const { queryString, terms, delegatorName = SearchDelegatorName.DEFAULT } = parsedQuery;
|
|
|
+ const nqDeledator = this.nqDelegators[delegatorName];
|
|
|
|
|
|
const data = {
|
|
|
queryString,
|
|
|
- terms: terms as QueryTerms,
|
|
|
+ terms,
|
|
|
};
|
|
|
- return [this.nqDelegators[SearchDelegatorName.DEFAULT], data];
|
|
|
+ return [nqDeledator, data];
|
|
|
}
|
|
|
|
|
|
- async searchKeyword(keyword: string, user, userGroups, searchOpts): Promise<[ISearchResult<unknown>, string]> {
|
|
|
- let parsedQuery;
|
|
|
+ async searchKeyword(keyword: string, user, userGroups, searchOpts): Promise<[ISearchResult<unknown>, string | null]> {
|
|
|
+ let parsedQuery: ParsedQuery;
|
|
|
// parse
|
|
|
try {
|
|
|
parsedQuery = await this.parseSearchQuery(keyword);
|
|
|
@@ -251,8 +244,8 @@ class SearchService implements SearchQueryParser, SearchResolver {
|
|
|
throw err;
|
|
|
}
|
|
|
|
|
|
- let delegator;
|
|
|
- let data;
|
|
|
+ let delegator: SearchDelegator;
|
|
|
+ let data: SearchableData;
|
|
|
// resolve
|
|
|
try {
|
|
|
[delegator, data] = await this.resolve(parsedQuery);
|
|
|
@@ -262,7 +255,7 @@ class SearchService implements SearchQueryParser, SearchResolver {
|
|
|
throw err;
|
|
|
}
|
|
|
|
|
|
- return [await delegator.search(data, user, userGroups, searchOpts), delegator.name];
|
|
|
+ return [await delegator.search(data, user, userGroups, searchOpts), delegator.name ?? null];
|
|
|
}
|
|
|
|
|
|
parseQueryString(queryString: string): QueryTerms {
|