Blame view

HighLevelDesign.md 6.1 KB
be52af70   tangwang   first commit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
  
  店匠是类似于shopify的独立站SAAS。我们要为基于店匠的独立站(一般为跨境电商独立站)做搜索SAAS。
  
  
  ## 商品数据 - 数据源 - mysql
  店匠的商品结构如下:
  
  数据库配置:
  
  ## mysql数据源
  host: 120.79.247.228
  port: 3316
  username: saas
  password: P89cZHS5d7dFyc9R
  
  
  ### 店匠主表
  shoplazza_product_sku
  shoplazza_product_spu
  
  主表sku表的结构为:
  id	bigint(20)
  spu_id	bigint(20)
  shop_id	bigint(20)
  shoplazza_id	varchar(64)
  shoplazza_product_id	varchar(64)
  shoplazza_image_id	varchar(64)
  title	varchar(500)
  sku	varchar(100)
  barcode	varchar(100)
  position	int(11)
  price	decimal(10,2)
  compare_at_price	decimal(10,2)
  cost_price	decimal(10,2)
  option1	varchar(255)
  option2	varchar(255)
  option3	varchar(255)
  inventory_quantity	int(11)
  weight	decimal(10,2)
  weight_unit	varchar(10)
  image_src	varchar(500)
  wholesale_price	json
  note	text
  extend	json
  shoplazza_created_at	datetime
  shoplazza_updated_at	datetime
  tenant_id	bigint(20)
  creator	varchar(64)
  create_time	datetime
  updater	varchar(64)
  update_time	datetime
  deleted	bit(1)
  
  所有租户共用这个主表
  
  ### 每个租户的辅表
  各个租户,有自己的扩展表。 入索引的时候,商品主表 shoplazza_product_sku 的 id + shopid,拼接租户自己单独的扩展表(比如可以放一些自己的属性体系、各种语言的商品名、品牌名、标签、分类等)
  
  但是,各个租户,可能有不一样的业务数据,比如不同租户有不同的属性的体系、不同语言的商品标题(一般至少有中英文两种满足跨境的搜索需求),有不同的权重(提权)字段、业务过滤和聚合字段。
  能够统一的 只能是 sku表 按照一套配置规范、做一个配置文件,按照配置文件建设ES mapping结构以及做数据的入库。
  
  ## SearchEngine
  
  ### IndexerConfig
   @阿里opensearch电商行业.md, 有两套配置
  1. 应用结构配置 : 定义了ES的输入数据有哪些字段、关联mysql的哪些字段.
  2. 索引结构配置 : 定义了ES的字段,每个字段的索引mapping配置,支持各个域的查询,包括默认的域的查询。索引配置预定一号了一堆分析方式 由 @商品数据源入ES配置规范.md 定义。
  
  
  
  ### 测试数据灌入
  
  灌入数据、mysql到ES的自动同步,不在本项目的范围内,另外有java项目负责。
  但是,该项目 为了提供测试数据,需要 构造一个实例 customer1.
  我们为他构造一套应用配置和索引配置。
  灌入一批测试数据,可以些一个简单的 全量灌入的实现。
  数据源地址在:data/customer1/goods_with_pic.5years_congku.csv.shuf.1w
  请根据这里面的字段,建设辅助表(注意看哪些字段在主表有,哪些需要放到辅表)
  然后写一个程序,将数据分别灌入主表和辅表。
  
  
  ### queryParser
  query分析,做以下几个事情:
  
  1. 查询改写。 配置词典的key是query,value是改写后的查询表达式,比如。比如品牌词 改写为在brand|query OR name|query,类别词、标签词等都可以放进去。纠错、规范化、查询改写等 都可以通过这个词典来配置。
  2. 翻译。配置需要得到的几种目标语言。 在customer1测试案例中,我们配置 zh en两种语言。先对query做语言检测,如果query是中文那么要翻译一下en,如果是en那么要翻译zh,如果两者都不是那么zh en都需要翻译。
  3. 如果配置打开了text_embedding查询,并且query 包含了default域的查询,那么要把default域的查询词转向量,后面searcher会用这个向量参与查询。
  翻译代码参考:
  ```
  import requests
  api_url = "https://api.deepl.com/v2/translate"
  headers = {
      "Authorization": "DeepL-Auth-Key YOUR_AUTH_KEY",
      "Content-Type": "application/json",
  }
  payload = {
      "text": ["要翻译的文本"],
      "target_lang": "ZH",  # 中文
  }
  
  response = requests.post(api_url, headers=headers, json=payload, timeout=10)
  
  if response.status_code == 200:
      data = response.json()
      translation = data["translations"][0]["text"]
      print(translation)
  ```
  
  ### searcher
  
  支持多种检索表达式:
  支持多种匹配方式,如AND、OR、RANK、NOTAND以及(),优先级从高到低为(),ANDNOT,AND,OR,RANK。
  
  default域的相关性,是代码里面单独计算,是特定的深度定制优化的,暂时不做配置化。
2a76641e   tangwang   config
115
116
  多语言搜索:
  对外提供的服务 用default域搜索就行,但是内部需要通过配置翻译为多种语言(配置几种目标语言 默认中文、英文,并且设置对应的检索域),然后分别到对应的字段搜索,中文字段到配置的中文title搜索,英文到对应的英文title搜索。
be52af70   tangwang   first commit
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
  
  暂时具体实现为 bm25()+0.2*text_embedding_relevence(也就是knn检索表达式的打分)
  bm25打分(base_query):
  "multi_match": {
      "query": search_query,
      "fields": match_fields,
      "minimum_should_match": "67%",
      "tie_breaker": 0.9,
      "boost": 1.0,  # Low boost for auxiliary keyword query
      "_name": "base_query"
  }
  
  text_embedding_relevence:
          knn_query = {
              "knn": {
                  "field": text_embedding_field,
                  "query_vector": query_vector.tolist(),
                  "k": KNN_K,
                  "num_candidates": KNN_NUM_CANDIDATES
              }
          }
  
  支持配置化的排序打分:
  default域 支持配置的排序方式:
  | 场景 | 表达式 | 含义 |
  |------|--------|------|
  | 电商 | `text_re()+general_score*2+timeliness(end_time)` | 文本分、宝贝综合分值、过期时间 |
  
  
  有一个配置,是否按照spu聚合,如果打开spu聚合,那么 要配置spu_id的字段,检索表达上需要加上:
  es_query["aggs"]["unique_count"] = {
      "cardinality": {
          "field": spu_id_field_name
      }
  }
  es_query["collapse"]["inner_hits"] = {
      "_source": False,
      "name": "top_docs",
      "size": INNER_HITS_SIZE
  }
  
  
  ## 相关配置
  
  ES_CONFIG = {
      'host': 'http://localhost:9200',
      'username': 'essa',
      'password': '4hOaLaf41y2VuI8y'
  }
  
  REDIS_CONFIG = {
      'host': 'localhost',
      'port': 6479,
      'password': 'BMfv5aI31kgHWtlx'
  }
  
  DEEPL_AUTH_KEY = "c9293ab4-ad25-479b-919f-ab4e63b429ed"