Просмотр исходного кода

refs #82628: fix search keyword result sorting
- Change for FB
- Replace search-axis-util
- Separate appendSortOrder method
- fix comment

NEEDLEMAN3\tatsu 4 лет назад
Родитель
Сommit
fe5fdadf16

+ 3 - 3
packages/app/src/components/SearchPage.jsx

@@ -11,7 +11,7 @@ import SearchPageLayout from './SearchPage/SearchPageLayout';
 import SearchResultContent from './SearchPage/SearchResultContent';
 import SearchResultList from './SearchPage/SearchResultList';
 import SearchControl from './SearchPage/SearchControl';
-import { SORT_AXIS_CONSTS, SORT_ORDER_CONSTS } from '~/utils/search-axis-utils';
+import { SORT_AXIS, SORT_ORDER } from '~/interfaces/search';
 
 export const specificPathNames = {
   user: '/user',
@@ -37,8 +37,8 @@ class SearchPage extends React.Component {
       pagingLimit: this.props.appContainer.config.pageLimitationL,
       excludeUserPages: true,
       excludeTrashPages: true,
-      sort: SORT_AXIS_CONSTS.score,
-      order: SORT_ORDER_CONSTS.desc,
+      sort: SORT_AXIS.RELATION_SCORE,
+      order: SORT_ORDER.DESC,
     };
 
     this.changeURL = this.changeURL.bind(this);

+ 12 - 14
packages/app/src/components/SearchPage/SearchControl.tsx

@@ -4,13 +4,11 @@ import SearchPageForm from './SearchPageForm';
 import AppContainer from '../../client/services/AppContainer';
 import DeleteSelectedPageGroup from './DeleteSelectedPageGroup';
 import SearchOptionModal from './SearchOptionModal';
-import { CheckboxType } from '../../interfaces/search';
-import {
-  SORT_AXIS, SORT_AXIS_CONSTS, SORT_ORDER, SORT_ORDER_CONSTS,
-} from '~/utils/search-axis-utils';
+import { CheckboxType, SORT_AXIS, SORT_ORDER } from '../../interfaces/search';
 
-const { score: sortByScore, updatedAt: sortByUpdatedAt, createdAt: sortByCreatedAt } = SORT_AXIS_CONSTS;
-const { desc, asc } = SORT_ORDER_CONSTS;
+
+const { RELATION_SCORE, UPDATED_AT, CREATED_AT } = SORT_AXIS;
+const { DESC, ASC } = SORT_ORDER;
 
 type Props = {
   searchingKeyword: string,
@@ -51,17 +49,17 @@ const SearchControl: FC <Props> = (props: Props) => {
     if (props.onChangeSortInvoked != null) {
       const getNextSort = (sort: SORT_AXIS) => {
         switch (sort) {
-          case sortByScore:
-            return sortByUpdatedAt;
-          case sortByUpdatedAt:
-            return sortByCreatedAt;
-          case sortByCreatedAt:
+          case RELATION_SCORE:
+            return UPDATED_AT;
+          case UPDATED_AT:
+            return CREATED_AT;
+          case CREATED_AT:
           default:
-            return sortByScore;
+            return RELATION_SCORE;
         }
       };
-      const nextSort = props.order === desc ? props.sort : getNextSort(props.sort);
-      const nextOrder = nextSort === props.sort ? asc : desc;
+      const nextSort = props.order === DESC ? props.sort : getNextSort(props.sort);
+      const nextOrder = nextSort === props.sort ? ASC : DESC;
       props.onChangeSortInvoked(nextSort, nextOrder);
     }
   };

+ 13 - 0
packages/app/src/interfaces/search.ts

@@ -16,3 +16,16 @@ export type IPageSearchResultData = {
     },
   },
 }
+
+export const SORT_AXIS = {
+  RELATION_SCORE: 'relationScore',
+  CREATED_AT: 'createdAt',
+  UPDATED_AT: 'updatedAt',
+} as const;
+export type SORT_AXIS = typeof SORT_AXIS[keyof typeof SORT_AXIS];
+
+export const SORT_ORDER = {
+  DESC: 'desc',
+  ASC: 'asc',
+} as const;
+export type SORT_ORDER = typeof SORT_ORDER[keyof typeof SORT_ORDER];

+ 35 - 14
packages/app/src/server/service/search-delegator/elasticsearch.ts

@@ -13,10 +13,7 @@ import {
   MetaData, SearchDelegator, Result, SearchableData, QueryTerms,
 } from '../../interfaces/search';
 import { SearchDelegatorName } from '~/interfaces/named-query';
-
-const {
-  SORT_AXIS, SORT_AXIS_CONSTS, SORT_ORDER, SORT_ORDER_CONSTS,
-} = require('~/utils/search-axis-utils');
+import { SORT_AXIS, SORT_ORDER } from '~/interfaces/search';
 
 const logger = loggerFactory('growi:service:search-delegator:elasticsearch');
 
@@ -24,6 +21,19 @@ const DEFAULT_OFFSET = 0;
 const DEFAULT_LIMIT = 50;
 const BULK_REINDEX_SIZE = 100;
 
+const { RELATION_SCORE, CREATED_AT, UPDATED_AT } = SORT_AXIS;
+const { DESC, ASC } = SORT_ORDER;
+
+const ES_SORT_AXIS = {
+  [RELATION_SCORE]: '_score',
+  [CREATED_AT]: 'created_at',
+  [UPDATED_AT]: 'updated_at',
+};
+const ES_SORT_ORDER = {
+  [DESC]: 'desc',
+  [ASC]: 'asc',
+};
+
 type Data = any;
 
 class ElasticsearchDelegator implements SearchDelegator<Data> {
@@ -615,12 +625,10 @@ class ElasticsearchDelegator implements SearchDelegator<Data> {
   /**
    * create search query for Elasticsearch
    *
-   * @param {SORT_AXIS} sort sort axis
-   * @param {SORT_ORDER} order sort order
    * @param {object | undefined} option optional paramas
    * @returns {object} query object
    */
-  createSearchQuery(sort, order, option?) {
+  createSearchQuery(option?) {
     let fields = ['path', 'bookmark_count', 'comment_count', 'seenUsers_count', 'updated_at', 'tag_names', 'comments'];
     if (option) {
       fields = option.fields || fields;
@@ -631,12 +639,10 @@ class ElasticsearchDelegator implements SearchDelegator<Data> {
       index: this.aliasName,
       type: 'pages',
       body: {
-        sort: [{ [sort]: { order } }],
         query: {}, // query
         _source: fields,
       },
     };
-    this.appendResultSize(query);
 
     return query;
   }
@@ -646,8 +652,22 @@ class ElasticsearchDelegator implements SearchDelegator<Data> {
     query.size = size || DEFAULT_LIMIT;
   }
 
+  appendSortOrder(query, sortAxis: SORT_AXIS, sortOrder: SORT_ORDER) {
+    // default sort order is score descending
+    const sort = ES_SORT_AXIS[sortAxis] || ES_SORT_AXIS[RELATION_SCORE];
+    const order = ES_SORT_ORDER[sortOrder] || ES_SORT_ORDER[DESC];
+    query.body.sort = { [sort]: { order } };
+  }
+
+  convertSortQuery(sortAxis) {
+    switch (sortAxis) {
+      case RELATION_SCORE:
+        return '_score';
+    }
+  }
+
   initializeBoolQuery(query) {
-    // query is created by ScreateSearchQuery()
+    // query is created by createSearchQuery()
     if (!query.body.query.bool) {
       query.body.query.bool = {};
     }
@@ -879,16 +899,17 @@ class ElasticsearchDelegator implements SearchDelegator<Data> {
 
     const from = option.offset || null;
     const size = option.limit || null;
-    // default sort order is score descending
-    const sort = option.sort || SORT_AXIS_CONSTS.score;
-    const order = option.order || SORT_ORDER_CONSTS.desc;
-    const query = this.createSearchQuery(sort, order);
+    const sort = option.sort || null;
+    const order = option.order || null;
+    const query = this.createSearchQuery();
     this.appendCriteriaForQueryString(query, terms);
 
     await this.filterPagesByViewer(query, user, userGroups);
 
     this.appendResultSize(query, from, size);
 
+    this.appendSortOrder(query, sort, order);
+
     await this.appendFunctionScore(query, queryString);
 
     return this.searchKeyword(query);

+ 0 - 24
packages/app/src/utils/search-axis-utils.ts

@@ -1,24 +0,0 @@
-
-const SORT_AXIS_CONSTS = {
-  score: '_score',
-  createdAt: 'created_at',
-  updatedAt: 'updated_at',
-};
-
-type SORT_AXIS = typeof SORT_AXIS_CONSTS[keyof typeof SORT_AXIS_CONSTS];
-
-const SORT_ORDER_CONSTS = {
-  desc: 'desc',
-  asc: 'asc',
-};
-type SORT_ORDER = typeof SORT_ORDER_CONSTS[keyof typeof SORT_ORDER_CONSTS];
-
-export type {
-  SORT_AXIS,
-  SORT_ORDER,
-};
-
-export {
-  SORT_AXIS_CONSTS,
-  SORT_ORDER_CONSTS,
-};