|
@@ -1,6 +1,7 @@
|
|
|
import { Client } from '@elastic/elasticsearch';
|
|
|
-import { Config, Init, Provide } from '@midwayjs/core';
|
|
|
-import { floor, get } from 'lodash';
|
|
|
+import { Config, Init, Inject, Provide } from '@midwayjs/core';
|
|
|
+import { Context } from '@midwayjs/koa';
|
|
|
+import { floor, get, head } from 'lodash';
|
|
|
|
|
|
@Provide()
|
|
|
export class AccurateMatchingService {
|
|
@@ -8,6 +9,9 @@ export class AccurateMatchingService {
|
|
|
esConfig: object;
|
|
|
/**es连接实例 */
|
|
|
esClient: Client;
|
|
|
+ @Inject()
|
|
|
+ ctx: Context;
|
|
|
+
|
|
|
@Init()
|
|
|
async initClient() {
|
|
|
const esClient = new Client(this.esConfig);
|
|
@@ -28,16 +32,18 @@ export class AccurateMatchingService {
|
|
|
return this.search(keyword, config, skip, limit);
|
|
|
}
|
|
|
|
|
|
- async forDemandSearch(keyword: string, skip = 0, limit = 10) {
|
|
|
- const fields = ['name', 'tags', 'area', 'brief'];
|
|
|
+ async forDemandSearch(keyword: string, skip = 0, limit = 10, id) {
|
|
|
+ const fields = ['name', 'tags', 'brief'];
|
|
|
const config = { index: ['supply', 'achievement'], fields };
|
|
|
- return await this.manyIndexsSearch(keyword, config, skip, limit);
|
|
|
+ const origin_index = 'demand';
|
|
|
+ return await this.manyIndexsSearch(keyword, config, skip, limit, origin_index, id);
|
|
|
}
|
|
|
|
|
|
- async forSupplySearch(keyword: string, skip = 0, limit = 10){
|
|
|
- const fields = ['name', 'tags', 'area', 'brief'];
|
|
|
+ async forSupplySearch(keyword: string, skip = 0, limit = 10, id) {
|
|
|
+ const fields = ['name', 'tags', 'brief'];
|
|
|
const config = { index: ['demand', 'achievement'], fields };
|
|
|
- return await this.manyIndexsSearch(keyword, config, skip, limit);
|
|
|
+ const origin_index = 'supply';
|
|
|
+ return await this.manyIndexsSearch(keyword, config, skip, limit, origin_index, id);
|
|
|
}
|
|
|
|
|
|
/**精准匹配统一查询,使用简单的form+size分页模式.如果数据量大于1w,此处的分页模式应该修改,不过就会影响资源的占用及数据的实时性 */
|
|
@@ -65,23 +71,60 @@ export class AccurateMatchingService {
|
|
|
return returnData;
|
|
|
}
|
|
|
|
|
|
- async manyIndexsSearch(keyword: string, config: object, skip: number, limit: number) {
|
|
|
+ async manyIndexsSearch(keyword: string, config: object, skip: number, limit: number, origin_index: string, id?: number) {
|
|
|
const index = get(config, 'index');
|
|
|
const fields = get(config, 'fields', []);
|
|
|
+ const user_id = get(this.ctx, 'user.id');
|
|
|
+ const must: any = [
|
|
|
+ {
|
|
|
+ multi_match: {
|
|
|
+ query: keyword,
|
|
|
+ fields,
|
|
|
+ type: 'best_fields',
|
|
|
+ tie_breaker: 0.5,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ const must_not = [
|
|
|
+ {
|
|
|
+ match: {
|
|
|
+ user: user_id,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ const filter = [];
|
|
|
+ if (id) {
|
|
|
+ const res = await this.esClient.search({
|
|
|
+ index: origin_index,
|
|
|
+ query: { bool: { must: { match: { id } } } },
|
|
|
+ });
|
|
|
+ const originResult = this.dealResponses(res);
|
|
|
+ const industry = get(head(get(originResult, 'data')), 'industry');
|
|
|
+ if (industry && industry !== '') {
|
|
|
+ filter.push({ term: { industry } });
|
|
|
+ }
|
|
|
+ }
|
|
|
const result = await this.esClient.search({
|
|
|
index,
|
|
|
query: {
|
|
|
bool: {
|
|
|
- must: [
|
|
|
- {
|
|
|
- multi_match: {
|
|
|
- query: keyword,
|
|
|
- fields,
|
|
|
- },
|
|
|
- },
|
|
|
- ],
|
|
|
+ must,
|
|
|
+ must_not,
|
|
|
+ filter,
|
|
|
},
|
|
|
},
|
|
|
+ // highlight: {
|
|
|
+ // fields: {
|
|
|
+ // name: {
|
|
|
+ // pre_tags: ['<em>'],
|
|
|
+ // post_tags: ['</em>'],
|
|
|
+ // },
|
|
|
+ // brief: {
|
|
|
+ // pre_tags: ['<em>'],
|
|
|
+ // post_tags: ['</em>'],
|
|
|
+ // },
|
|
|
+ // },
|
|
|
+ // },
|
|
|
size: limit,
|
|
|
from: skip,
|
|
|
});
|