Yuki Takei 7 лет назад
Родитель
Сommit
f32ccd6e05
2 измененных файлов с 27 добавлено и 30 удалено
  1. 2 8
      src/server/routes/search.js
  2. 25 22
      src/server/util/search.js

+ 2 - 8
src/server/routes/search.js

@@ -32,7 +32,7 @@ module.exports = function(crowi, app) {
    */
   api.search = async function(req, res) {
     const user = req.user;
-    const { q: keyword = null, tree = null, type = null } = req.query;
+    const { q: keyword = null, type = null } = req.query;
     let paginateOpts;
 
     try {
@@ -61,13 +61,7 @@ module.exports = function(crowi, app) {
 
     const result = {};
     try {
-      let esResult;
-      if (tree) {
-        esResult = await search.searchKeywordUnderPath(keyword, tree, user, userGroups, searchOpts);
-      }
-      else {
-        esResult = await search.searchKeyword(keyword, user, userGroups, searchOpts);
-      }
+      const esResult = await search.searchKeyword(keyword, user, userGroups, searchOpts);
 
       // create score map for sorting
       // key: id , value: score

+ 25 - 22
src/server/util/search.js

@@ -672,29 +672,13 @@ SearchClient.prototype.searchByPath = async function(keyword, prefix) {
   // TODO path 名だけから検索
 };
 
-SearchClient.prototype.searchKeywordUnderPath = async function(keyword, path, user, userGroups, option) {
-  const from = option.offset || null;
-  const size = option.limit || null;
-  const type = option.type || null;
-  const query = this.createSearchQuerySortedByScore();
-  this.appendCriteriaForKeywordContains(query, keyword);
-  this.appendCriteriaForPathFilter(query, path);
-
-  this.filterPagesByType(query, type);
-  await this.filterPagesByViewer(query, user, userGroups);
-
-  this.appendResultSize(query, from, size);
-
-  this.appendFunctionScore(query);
-
-  return this.search(query);
-};
-
 SearchClient.prototype.getParsedKeywords = function(keyword) {
   let matchWords = [];
   let notMatchWords = [];
   let phraseWords = [];
   let notPhraseWords = [];
+  let prefixPaths = [];
+  let notPrefixPaths = [];
 
   keyword.trim();
   keyword = keyword.replace(/\s+/g, ' ');
@@ -723,11 +707,28 @@ SearchClient.prototype.getParsedKeywords = function(keyword) {
       return;
     }
 
-    if (word.match(/^-(.+)$/)) {
-      notMatchWords.push(RegExp.$1);
+    // https://regex101.com/r/lN4LIV/1
+    const matchNegative = word.match(/^-(prefix:)?(.+)$/);
+    // https://regex101.com/r/gVssZe/1
+    const matchPositive = word.match(/^(prefix:)?(.+)$/);
+
+    if (matchNegative != null) {
+      const isPrefixCondition = (matchNegative[1] != null);
+      if (isPrefixCondition) {
+        notPrefixPaths.push(matchNegative[2]);
+      }
+      else {
+        notMatchWords.push(matchNegative[2]);
+      }
     }
-    else {
-      matchWords.push(word);
+    else if (matchPositive != null) {
+      const isPrefixCondition = (matchPositive[1] != null);
+      if (isPrefixCondition) {
+        prefixPaths.push(matchPositive[2]);
+      }
+      else {
+        matchWords.push(matchPositive[2]);
+      }
     }
   });
 
@@ -736,6 +737,8 @@ SearchClient.prototype.getParsedKeywords = function(keyword) {
     not_match: notMatchWords,
     phrase: phraseWords,
     not_phrase: notPhraseWords,
+    prefix: prefixPaths,
+    not_prefix: notPrefixPaths,
   };
 };