Browse Source

Merge branch 'feat/pt-dev-master' into feat/pt-dev-4

Taichi Masuyama 4 years ago
parent
commit
23adbfcd51

+ 1 - 54
packages/app/src/server/service/search-delegator/elasticsearch.ts

@@ -626,7 +626,7 @@ class ElasticsearchDelegator implements SearchDelegator<Data> {
     return query;
     return query;
   }
   }
 
 
-  createSearchQuerySortedByScore(option) {
+  createSearchQuerySortedByScore(option?) {
     let fields = ['path', 'bookmark_count', 'comment_count', 'seenUsers_count', 'updated_at', 'tag_names', 'comments'];
     let fields = ['path', 'bookmark_count', 'comment_count', 'seenUsers_count', 'updated_at', 'tag_names', 'comments'];
     if (option) {
     if (option) {
       fields = option.fields || fields;
       fields = option.fields || fields;
@@ -867,7 +867,6 @@ class ElasticsearchDelegator implements SearchDelegator<Data> {
     };
     };
   }
   }
 
 
-<<<<<<< HEAD:packages/app/src/server/service/search-delegator/elasticsearch.js
   appendHighlight(query) {
   appendHighlight(query) {
     query.body.highlight = {
     query.body.highlight = {
       fields: {
       fields: {
@@ -881,12 +880,9 @@ class ElasticsearchDelegator implements SearchDelegator<Data> {
     };
     };
   }
   }
 
 
-  async searchKeyword(queryString, user, userGroups, option) {
-=======
   async search(data: SearchableData, user, userGroups, option): Promise<Result<Data> & MetaData> {
   async search(data: SearchableData, user, userGroups, option): Promise<Result<Data> & MetaData> {
     const { queryString, terms } = data;
     const { queryString, terms } = data;
 
 
->>>>>>> feat/pt-dev-master:packages/app/src/server/service/search-delegator/elasticsearch.ts
     const from = option.offset || null;
     const from = option.offset || null;
     const size = option.limit || null;
     const size = option.limit || null;
     const query = this.createSearchQuerySortedByScore();
     const query = this.createSearchQuerySortedByScore();
@@ -896,56 +892,7 @@ class ElasticsearchDelegator implements SearchDelegator<Data> {
 
 
     this.appendResultSize(query, from, size);
     this.appendResultSize(query, from, size);
 
 
-<<<<<<< HEAD:packages/app/src/server/service/search-delegator/elasticsearch.js
-    this.appendFunctionScore(query, queryString);
-    this.appendHighlight(query);
-    return this.search(query);
-  }
-
-  parseQueryString(queryString) {
-    const matchWords = [];
-    const notMatchWords = [];
-    const phraseWords = [];
-    const notPhraseWords = [];
-    const prefixPaths = [];
-    const notPrefixPaths = [];
-    const tags = [];
-    const notTags = [];
-
-    queryString.trim();
-    queryString = queryString.replace(/\s+/g, ' '); // eslint-disable-line no-param-reassign
-
-    // First: Parse phrase keywords
-    const phraseRegExp = new RegExp(/(-?"[^"]+")/g);
-    const phrases = queryString.match(phraseRegExp);
-
-    if (phrases !== null) {
-      queryString = queryString.replace(phraseRegExp, ''); // eslint-disable-line no-param-reassign
-
-      phrases.forEach((phrase) => {
-        phrase.trim();
-        if (phrase.match(/^-/)) {
-          notPhraseWords.push(phrase.replace(/^-/, ''));
-        }
-        else {
-          phraseWords.push(phrase);
-        }
-      });
-    }
-
-    // Second: Parse other keywords (include minus keywords)
-    queryString.split(' ').forEach((word) => {
-      if (word === '') {
-        return;
-      }
-
-      // https://regex101.com/r/pN9XfK/1
-      const matchNegative = word.match(/^-(prefix:|tag:)?(.+)$/);
-      // https://regex101.com/r/3qw9FQ/1
-      const matchPositive = word.match(/^(prefix:|tag:)?(.+)$/);
-=======
     await this.appendFunctionScore(query, queryString);
     await this.appendFunctionScore(query, queryString);
->>>>>>> feat/pt-dev-master:packages/app/src/server/service/search-delegator/elasticsearch.ts
 
 
     return this.searchKeyword(query);
     return this.searchKeyword(query);
   }
   }

+ 0 - 187
packages/app/src/server/service/search.js

@@ -1,187 +0,0 @@
-import loggerFactory from '~/utils/logger';
-
-// eslint-disable-next-line no-unused-vars
-const logger = loggerFactory('growi:service:search');
-const xss = require('xss');
-
-// options for filtering xss
-const filterXssOptions = {
-  whiteList: {
-    em: ['class'],
-  },
-};
-
-const filterXss = new xss.FilterXSS(filterXssOptions);
-
-class SearchService {
-
-  constructor(crowi) {
-    this.crowi = crowi;
-    this.configManager = crowi.configManager;
-
-    this.isErrorOccuredOnHealthcheck = null;
-    this.isErrorOccuredOnSearching = null;
-
-    try {
-      this.delegator = this.generateDelegator();
-    }
-    catch (err) {
-      logger.error(err);
-    }
-
-    if (this.isConfigured) {
-      this.delegator.init();
-      this.registerUpdateEvent();
-    }
-  }
-
-  get isConfigured() {
-    return this.delegator != null;
-  }
-
-  get isReachable() {
-    return this.isConfigured && !this.isErrorOccuredOnHealthcheck && !this.isErrorOccuredOnSearching;
-  }
-
-  get isSearchboxEnabled() {
-    const uri = this.configManager.getConfig('crowi', 'app:searchboxSslUrl');
-    return uri != null && uri.length > 0;
-  }
-
-  get isElasticsearchEnabled() {
-    const uri = this.configManager.getConfig('crowi', 'app:elasticsearchUri');
-    return uri != null && uri.length > 0;
-  }
-
-  generateDelegator() {
-    logger.info('Initializing search delegator');
-
-    if (this.isSearchboxEnabled) {
-      const SearchboxDelegator = require('./search-delegator/searchbox');
-      logger.info('Searchbox is enabled');
-      return new SearchboxDelegator(this.configManager, this.crowi.socketIoService);
-    }
-    if (this.isElasticsearchEnabled) {
-      const ElasticsearchDelegator = require('./search-delegator/elasticsearch');
-      logger.info('Elasticsearch (not Searchbox) is enabled');
-      return new ElasticsearchDelegator(this.configManager, this.crowi.socketIoService);
-    }
-
-    logger.info('No elasticsearch URI is specified so that full text search is disabled.');
-  }
-
-  registerUpdateEvent() {
-    const pageEvent = this.crowi.event('page');
-    pageEvent.on('create', this.delegator.syncPageUpdated.bind(this.delegator));
-    pageEvent.on('update', this.delegator.syncPageUpdated.bind(this.delegator));
-    pageEvent.on('deleteCompletely', this.delegator.syncPagesDeletedCompletely.bind(this.delegator));
-    pageEvent.on('delete', this.delegator.syncPageDeleted.bind(this.delegator));
-    pageEvent.on('updateMany', this.delegator.syncPagesUpdated.bind(this.delegator));
-    pageEvent.on('syncDescendants', this.delegator.syncDescendantsPagesUpdated.bind(this.delegator));
-    pageEvent.on('addSeenUsers', this.delegator.syncPageUpdated.bind(this.delegator));
-
-    const bookmarkEvent = this.crowi.event('bookmark');
-    bookmarkEvent.on('create', this.delegator.syncBookmarkChanged.bind(this.delegator));
-    bookmarkEvent.on('delete', this.delegator.syncBookmarkChanged.bind(this.delegator));
-
-    const commentEvent = this.crowi.event('comment');
-    commentEvent.on('create', this.delegator.syncCommentChanged.bind(this.delegator));
-    commentEvent.on('update', this.delegator.syncCommentChanged.bind(this.delegator));
-    commentEvent.on('delete', this.delegator.syncCommentChanged.bind(this.delegator));
-
-    const tagEvent = this.crowi.event('tag');
-    tagEvent.on('update', this.delegator.syncTagChanged.bind(this.delegator));
-  }
-
-  resetErrorStatus() {
-    this.isErrorOccuredOnHealthcheck = false;
-    this.isErrorOccuredOnSearching = false;
-  }
-
-  async reconnectClient() {
-    logger.info('Try to reconnect...');
-    this.delegator.initClient();
-
-    try {
-      await this.getInfoForHealth();
-
-      logger.info('Reconnecting succeeded.');
-      this.resetErrorStatus();
-    }
-    catch (err) {
-      throw err;
-    }
-  }
-
-  async getInfo() {
-    try {
-      return await this.delegator.getInfo();
-    }
-    catch (err) {
-      logger.error(err);
-      throw err;
-    }
-  }
-
-  async getInfoForHealth() {
-    try {
-      const result = await this.delegator.getInfoForHealth();
-
-      this.isErrorOccuredOnHealthcheck = false;
-      return result;
-    }
-    catch (err) {
-      logger.error(err);
-
-      // switch error flag, `isErrorOccuredOnHealthcheck` to be `false`
-      this.isErrorOccuredOnHealthcheck = true;
-      throw err;
-    }
-  }
-
-  async getInfoForAdmin() {
-    return this.delegator.getInfoForAdmin();
-  }
-
-  async normalizeIndices() {
-    return this.delegator.normalizeIndices();
-  }
-
-  async rebuildIndex() {
-    return this.delegator.rebuildIndex();
-  }
-
-  async searchKeyword(keyword, user, userGroups, searchOpts) {
-    try {
-      return await this.delegator.searchKeyword(keyword, user, userGroups, searchOpts);
-    }
-    catch (err) {
-      logger.error(err);
-
-      // switch error flag, `isReachable` to be `false`
-      this.isErrorOccuredOnSearching = true;
-      throw err;
-    }
-  }
-
-  /**
-   * formatting result
-   */
-  formatResult(esResult) {
-    esResult.data.forEach((data) => {
-      const highlightData = data._highlight;
-      const snippet = highlightData['body.en'] || highlightData['body.ja'] || '';
-      const pathMatch = highlightData['path.en'] || highlightData['path.ja'] || '';
-
-      data.elasticSearchResult = {
-        snippet: filterXss.process(snippet),
-        // todo: use filter xss.process() for matchedPath;
-        matchedPath: pathMatch,
-      };
-    });
-    return esResult;
-  }
-
-}
-
-module.exports = SearchService;

+ 1 - 1
packages/app/src/server/service/search.ts

@@ -106,7 +106,7 @@ class SearchService implements SearchQueryParser, SearchResolver {
     pageEvent.on('delete', this.fullTextSearchDelegator.syncPageDeleted.bind(this.fullTextSearchDelegator));
     pageEvent.on('delete', this.fullTextSearchDelegator.syncPageDeleted.bind(this.fullTextSearchDelegator));
     pageEvent.on('updateMany', this.fullTextSearchDelegator.syncPagesUpdated.bind(this.fullTextSearchDelegator));
     pageEvent.on('updateMany', this.fullTextSearchDelegator.syncPagesUpdated.bind(this.fullTextSearchDelegator));
     pageEvent.on('syncDescendants', this.fullTextSearchDelegator.syncDescendantsPagesUpdated.bind(this.fullTextSearchDelegator));
     pageEvent.on('syncDescendants', this.fullTextSearchDelegator.syncDescendantsPagesUpdated.bind(this.fullTextSearchDelegator));
-    pageEvent.on('addSeenUsers', this.delegator.syncPageUpdated.bind(this.delegator));
+    pageEvent.on('addSeenUsers', this.fullTextSearchDelegator.syncPageUpdated.bind(this.fullTextSearchDelegator));
 
 
     const bookmarkEvent = this.crowi.event('bookmark');
     const bookmarkEvent = this.crowi.event('bookmark');
     bookmarkEvent.on('create', this.fullTextSearchDelegator.syncBookmarkChanged.bind(this.fullTextSearchDelegator));
     bookmarkEvent.on('create', this.fullTextSearchDelegator.syncBookmarkChanged.bind(this.fullTextSearchDelegator));

+ 0 - 5
yarn.lock

@@ -16496,11 +16496,6 @@ react-multiline-clamp@^2.0.0:
   resolved "https://registry.yarnpkg.com/react-multiline-clamp/-/react-multiline-clamp-2.0.0.tgz#913a2092368ef1b52c1c79364d506ba4af27e019"
   resolved "https://registry.yarnpkg.com/react-multiline-clamp/-/react-multiline-clamp-2.0.0.tgz#913a2092368ef1b52c1c79364d506ba4af27e019"
   integrity sha512-iPm3HxFD6LO63lE5ZnThiqs+6A3c+LW3WbsEM0oa0iNTa0qN4SKx/LK/6ZToSmXundEcQXBFVNzKDvgmExawTw==
   integrity sha512-iPm3HxFD6LO63lE5ZnThiqs+6A3c+LW3WbsEM0oa0iNTa0qN4SKx/LK/6ZToSmXundEcQXBFVNzKDvgmExawTw==
 
 
-react-node-resolver@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/react-node-resolver/-/react-node-resolver-1.0.1.tgz#1798a729c0e218bf2f0e8ddf79c550d4af61d83a"
-  integrity sha1-F5inKcDiGL8vDo3fecVQ1K9h2Do=
-
 react-overlays@^0.8.1:
 react-overlays@^0.8.1:
   version "0.8.3"
   version "0.8.3"
   resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-0.8.3.tgz#fad65eea5b24301cca192a169f5dddb0b20d3ac5"
   resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-0.8.3.tgz#fad65eea5b24301cca192a169f5dddb0b20d3ac5"