Browse Source

索引修改,行业改为关键词,精确查询,联系方式查询都修改

lrf 6 tháng trước cách đây
mục cha
commit
bc6f892667

+ 2 - 1
dict.txt

@@ -2,4 +2,5 @@
 合金开发
 合金
 性能
-爱喝紫色汽水
+人工智能
+处理

+ 4 - 4
src/controller/accurateMatching.controller.ts

@@ -12,16 +12,16 @@ export class AccurateMatchingController {
    * @param limit 分页显示数量
    */
   @Get('/demand')
-  async demand(@Query('keyword') keyword: string, @Query('skip') skip: number, @Query('limit') limit: number) {
+  async demand(@Query('keyword') keyword: string, @Query('skip') skip: number, @Query('limit') limit: number, @Query('id') id: number) {
     // const result = await this.amService.demand(keyword, skip, limit);
-    const result = await this.amService.forDemandSearch(keyword, skip, limit);
+    const result = await this.amService.forDemandSearch(keyword, skip, limit, id);
     return result;
   }
 
   @Get('/supply')
-  async supply(@Query('keyword') keyword: string, @Query('skip') skip: number, @Query('limit') limit: number) {
+  async supply(@Query('keyword') keyword: string, @Query('skip') skip: number, @Query('limit') limit: number, @Query('id') id: number) {
     // const result = await this.amService.supply(keyword, skip, limit);
-    const result = await this.amService.forSupplySearch(keyword, skip, limit);
+    const result = await this.amService.forSupplySearch(keyword, skip, limit, id);
     return result;
   }
 

+ 9 - 9
src/controller/contactSearch.controller.ts

@@ -15,12 +15,12 @@ export class ContactSearchController {
    * @param keyword 关键词
    */
   @Get('/demand')
-  async demand(@Query('keyword') keyword: string) {
+  async demand(@Query('keyword') keyword: string, @Query('id') id: number) {
     if (!keyword) return;
     const supplyConfig = { index: 'supply', fields: ['name', 'tags', 'brief'] };
-    const sres = await this.csService.search(keyword, supplyConfig);
+    const sres = await this.csService.search(keyword, supplyConfig, 'demand', id);
     const achievementConfig = { index: 'achievement', fields: ['name', 'tags', 'brief'] };
-    const ares = await this.csService.search(keyword, achievementConfig);
+    const ares = await this.csService.search(keyword, achievementConfig, 'demand', id);
     return sres || ares;
   }
 
@@ -30,9 +30,9 @@ export class ContactSearchController {
    * @param keyword 关键词
    */
   @Get('/supply')
-  async supply(@Query('keyword') keyword: string) {
+  async supply(@Query('keyword') keyword: string, @Query('id') id: number) {
     const config = { index: 'demand', fields: ['name', 'tags', 'brief'] };
-    const res = await this.csService.search(keyword, config);
+    const res = await this.csService.search(keyword, config, 'supply', id);
     return res;
   }
 
@@ -42,9 +42,9 @@ export class ContactSearchController {
    * @param keyword 关键词
    */
   @Get('/project')
-  async projectr(@Query('keyword') keyword: string) {
+  async projectr(@Query('keyword') keyword: string, @Query('id') id: number) {
     const config = { index: 'demand', fields: ['name', 'tags', 'brief'] };
-    const res = await this.csService.search(keyword, config);
+    const res = await this.csService.search(keyword, config, 'project', id);
     return res;
   }
 
@@ -54,9 +54,9 @@ export class ContactSearchController {
    * @param keyword 关键词
    */
   @Get('/achievement')
-  async achievement(@Query('keyword') keyword: string) {
+  async achievement(@Query('keyword') keyword: string, @Query('id') id: number) {
     const config = { index: 'demand', fields: ['name', 'tags', 'brief'] };
-    const res = await this.csService.search(keyword, config);
+    const res = await this.csService.search(keyword, config, 'achievement', id);
     return res;
   }
 }

+ 1 - 1
src/controller/init.controller.ts

@@ -19,7 +19,7 @@ export class InitController {
 
   @Post('/data')
   async data(@Body('index') index: string, @Body('data') data: Array<any>) {
-    console.log('in init data')
+    console.log(`in init data: ${index} - ${data.length}`)
     await this.esService.initData(index, data);
     return 'ok'
   }

+ 60 - 17
src/service/accurateMatching.service.ts

@@ -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,
     });

+ 59 - 5
src/service/contactSearch.service.ts

@@ -16,8 +16,19 @@ export class ContactSearchService {
     const esClient = new Client(this.esConfig);
     this.esClient = esClient;
   }
-
-  async search(keyword: string, config: object) {
+  /**
+   * 联系申请相似度查询
+   * 正反两次验证:
+   *  1.正向验证: 由 查看的数据 点击 联系预约 提供的关键词 去指定索引查询并查看相似度,(取10条,但是只用第一条数据做判断,因为第一条数据是相似度最高的)
+   *    再查看是否有相似度 大于等于4 的数据,如果有.则允许该联系申请
+   *  2.如果正向查询的相似度 不大于等于4,则反过来用10条数据 针对 当前数据进行查询计算相似度
+   * @param keyword 关键词
+   * @param config 查询配置
+   * @param form 联系申请是由哪里的数据发生的,数据来源:source
+   * @param id  来源数据id:source_id
+   * @returns
+   */
+  async search(keyword: string, config: object, form: string, id: number) {
     const index = get(config, 'index');
     const fields = get(config, 'fields', []);
     const user_id = get(this.ctx, 'user.id');
@@ -43,16 +54,59 @@ export class ContactSearchService {
         },
       },
       from: 0,
-      size: 1,
+      size: 10,
     };
     const result = await this.esClient.search(searchObject);
     const returnData = this.dealResponses(result);
+    const list = get(returnData, 'data', []); //最符合正向匹配的前10个数据
     // 查找,是否有推荐度为4或4以上的数据.
-    const data = head(get(returnData, 'data', []));
+    const data = head(list);
     if (!data) return false;
     else {
+      // 先看下正向匹配(由 浏览数据的 标题 作为关键词, 到用户审核过的数据中进行查询)
       const recommend = get(data, '_recommend', 0);
-      return recommend >= 4;
+      const firRecommend = recommend >= 4;
+      // 如果大于等于4,则返回成功
+      if (firRecommend) return true;
+      let secRecommend = false;
+      // 如果不大于等于4,再依次使用查出来的结果,反向查询一下相似度
+      for (const i of list) {
+        const sourceKeyword = get(i, 'name');
+        const upDownSearchObject = {
+          index: form,
+          query: {
+            bool: {
+              must: [
+                {
+                  multi_match: {
+                    query: sourceKeyword,
+                    fields,
+                  },
+                },
+                {
+                  match_phrase: { status: '1' },
+                },
+                {
+                  match_phrase: { id },
+                },
+              ],
+            },
+          },
+          from: 0,
+          size: 1,
+        };
+        const fromResult = await this.esClient.search(upDownSearchObject);
+        const fromResponse = this.dealResponses(fromResult);
+        const fromList = get(fromResponse, 'data', []);
+        const fromData = head(fromList);
+        if (!fromData) continue;
+        const fromRecommend = get(fromData, '_recommend', 0);
+        if (fromRecommend >= 4) {
+          secRecommend = true;
+          break;
+        }
+      }
+      return secRecommend;
     }
   }
 

+ 10 - 10
src/service/elasticsearch/indices.ts

@@ -3,7 +3,7 @@ const indices = {
   achievement: {
     id: 'number',
     user: 'number',
-    industry: 'text',
+    industry: 'keyword',
     tags: 'text',
     patent: 'text',
     name: 'text',
@@ -39,7 +39,7 @@ const indices = {
     area: 'text',
     brief: 'text',
     demand_status: 'text',
-    industry: 'text',
+    industry: 'keyword',
     company: 'text',
     company_brief: 'text',
     contacts: 'text',
@@ -55,7 +55,7 @@ const indices = {
     id: 'number',
     user: 'number',
     file: 'nested',
-    industry: 'text',
+    industry: 'keyword',
     tags: 'text',
     name: 'text',
     build: 'text',
@@ -80,7 +80,7 @@ const indices = {
     href: 'text',
     work: 'text',
     address: 'text',
-    industry: 'text',
+    industry: 'keyword',
     form: 'text',
     start_time: 'date',
     end_time: 'date',
@@ -111,7 +111,7 @@ const indices = {
     progress: 'text',
     track_unit: 'text',
     source: 'text',
-    industry: 'text',
+    industry: 'keyword',
     file: 'nested',
     is_use: 'keyword',
     status: 'keyword',
@@ -131,7 +131,7 @@ const indices = {
     area: 'text',
     brief: 'text',
     demand_status: 'text',
-    industry: 'text',
+    industry: 'keyword',
     source: 'text',
     is_use: 'keyword',
     status: 'keyword',
@@ -140,7 +140,7 @@ const indices = {
     id: 'number',
     user: 'number',
     file: 'nested',
-    industry: 'text',
+    industry: 'keyword',
     tags: 'text',
     name: 'text',
     field: 'text',
@@ -156,7 +156,7 @@ const indices = {
   company: {
     id: 'number',
     user: 'number',
-    industry: 'text',
+    industry: 'keyword',
     tags: 'text',
     name: 'text',
     logo: 'nested',
@@ -204,7 +204,7 @@ const indices = {
   incubator: {
     id: 'number',
     user: 'number',
-    industry: 'text',
+    industry: 'keyword',
     tags: 'text',
     name: 'text',
     person: 'keyword',
@@ -242,7 +242,7 @@ const indices = {
 
 const getType = type => {
   const types = {
-    text: { type: 'text', analyzer: 'ik_max_word', search_analyzer: 'ik_smart' },
+    text: { type: 'text', analyzer: 'ik_smart', search_analyzer: 'ik_smart' },
     keyword: { type: 'keyword' },
     number: { type: 'integer' },
     long: { type: 'long' },