如何使用多个实体绑定设置 ElasticSearch 索引结构
How to setup ElasticSearch index structure with multiple entity bindings
最近,我开始使用 MySQL 将 ElasticSearch (ES) 实施到用 PHP 编写的遗留 e-commerce 应用程序中。我对所有这些东西都是全新的,阅读文档很好,但我真的需要有经验的人给我建议。
根据 ES 文档,我能够设置一个新的集群,我还发现河流已被弃用,应该被替换,所以我用 Logstash 和 JDBC MySQL 连接器替换了它们。
此时我有:
- 弹性搜索
- Logstash
- JDBC MySQL driver
- MySQL 服务器
应用的数据库结构并不是最优的,很难被替换,但我想以最好的方式将它复制到ES索引中。
数据库结构:
产品
+-------------------------------+-------+--------+
| Id | Title | Price |
+-------------------------------+-------+--------+
| 00c8234d71c4e94f725cd432ebc04 | Alpha | 589,00 |
| 018357657529fef056cf396626812 | Beta | 355,00 |
| 01a2c32ceeff0fc6b7dd4fc4302ab | Gamma | 0,00 |
+-------------------------------+-------+--------+
旗帜
+------------+-------------+
| Id | Title |
+------------+-------------+
| sellout | Sellout |
| discount | Discount |
| topproduct | Top Product |
+------------+-------------+
flagsProducts(n:m 枢轴)
+------+-------------------------------+------------+------------+
| Id | ProductId | FlagId | ExternalId |
+------+-------------------------------+------------+------------+
| 1552 | 00c8234d71c4e94f725cd432ebc04 | sellout | NULL |
| 2845 | 00c8234d71c4e94f725cd432ebc04 | topproduct | NULL |
| 9689 | 018357657529fef056cf396626812 | discount | NULL |
| 4841 | 01a2c32ceeff0fc6b7dd4fc4302ab | discount | NULL |
+------+-------------------------------+------------+------------+
那些字符串 ID 完全是一场灾难(但我现在必须处理它们)。一开始我觉得应该做一个扁平结构的Products索引到ES,但是多实体绑定呢?
这是一个很好的开始!
我肯定会把它全部弄平(即 denormalize)并提出如下所示的产品文档。这样你就可以通过简单地为每个产品创建一个 flags
数组来摆脱产品和标志之间的 N:M 关系。因此查询这些标志会更容易。
{
"id": "00c8234d71c4e94f725cd432ebc04",
"title": "Alpha",
"price": 589.0,
"flags": ["Sellout", "Top Product"]
}
{
"id": "018357657529fef056cf396626812",
"title": "Beta",
"price": 355.0,
"flags": ["Discount"]
}
{
"id": "01a2c32ceeff0fc6b7dd4fc4302ab",
"title": "Gamma",
"price": 0.0,
"flags": ["Discount"]
}
产品映射类型如下所示:
PUT products
{
"mappings": {
"product": {
"properties": {
"id": {
"type": "string",
"index": "not_analyzed"
},
"title": {
"type": "string"
},
"price": {
"type": "double",
"null_value": 0.0
},
"flags": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
由于您已经输入了 logstash jdbc
,您所缺少的只是获取产品和相关标志的正确 SQL 查询。
SELECT p.Id as id, p.Title as title, p.Price as price, GROUP_CONCAT(f.Title) as flags
FROM Products p
JOIN flagsProducts fp ON fp.ProductId = p.Id
JOIN Flags f ON fp.FlagId = f.id
GROUP BY p.Id
这会让你得到像这样的行:
+-------------------------------+-------+-------+---------------------+
| id | title | price | flags |
+-------------------------------+-------+-------+---------------------+
| 00c8234d71c4e94f725cd432ebc04 | Alpha | 589 | Sellout,Top product |
| 018357657529fef056cf396626812 | Beta | 355 | Discount |
| 01a2c32ceeff0fc6b7dd4fc4302ab | Gamma | 0 | Discount |
+-------------------------------+-------+-------+---------------------+
使用 Logstash 过滤器,然后您可以将 flags
拆分成一个数组,您就可以开始了。
最近,我开始使用 MySQL 将 ElasticSearch (ES) 实施到用 PHP 编写的遗留 e-commerce 应用程序中。我对所有这些东西都是全新的,阅读文档很好,但我真的需要有经验的人给我建议。
根据 ES 文档,我能够设置一个新的集群,我还发现河流已被弃用,应该被替换,所以我用 Logstash 和 JDBC MySQL 连接器替换了它们。
此时我有:
- 弹性搜索
- Logstash
- JDBC MySQL driver
- MySQL 服务器
应用的数据库结构并不是最优的,很难被替换,但我想以最好的方式将它复制到ES索引中。
数据库结构:
产品
+-------------------------------+-------+--------+
| Id | Title | Price |
+-------------------------------+-------+--------+
| 00c8234d71c4e94f725cd432ebc04 | Alpha | 589,00 |
| 018357657529fef056cf396626812 | Beta | 355,00 |
| 01a2c32ceeff0fc6b7dd4fc4302ab | Gamma | 0,00 |
+-------------------------------+-------+--------+
旗帜
+------------+-------------+
| Id | Title |
+------------+-------------+
| sellout | Sellout |
| discount | Discount |
| topproduct | Top Product |
+------------+-------------+
flagsProducts(n:m 枢轴)
+------+-------------------------------+------------+------------+
| Id | ProductId | FlagId | ExternalId |
+------+-------------------------------+------------+------------+
| 1552 | 00c8234d71c4e94f725cd432ebc04 | sellout | NULL |
| 2845 | 00c8234d71c4e94f725cd432ebc04 | topproduct | NULL |
| 9689 | 018357657529fef056cf396626812 | discount | NULL |
| 4841 | 01a2c32ceeff0fc6b7dd4fc4302ab | discount | NULL |
+------+-------------------------------+------------+------------+
那些字符串 ID 完全是一场灾难(但我现在必须处理它们)。一开始我觉得应该做一个扁平结构的Products索引到ES,但是多实体绑定呢?
这是一个很好的开始!
我肯定会把它全部弄平(即 denormalize)并提出如下所示的产品文档。这样你就可以通过简单地为每个产品创建一个 flags
数组来摆脱产品和标志之间的 N:M 关系。因此查询这些标志会更容易。
{
"id": "00c8234d71c4e94f725cd432ebc04",
"title": "Alpha",
"price": 589.0,
"flags": ["Sellout", "Top Product"]
}
{
"id": "018357657529fef056cf396626812",
"title": "Beta",
"price": 355.0,
"flags": ["Discount"]
}
{
"id": "01a2c32ceeff0fc6b7dd4fc4302ab",
"title": "Gamma",
"price": 0.0,
"flags": ["Discount"]
}
产品映射类型如下所示:
PUT products
{
"mappings": {
"product": {
"properties": {
"id": {
"type": "string",
"index": "not_analyzed"
},
"title": {
"type": "string"
},
"price": {
"type": "double",
"null_value": 0.0
},
"flags": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
由于您已经输入了 logstash jdbc
,您所缺少的只是获取产品和相关标志的正确 SQL 查询。
SELECT p.Id as id, p.Title as title, p.Price as price, GROUP_CONCAT(f.Title) as flags
FROM Products p
JOIN flagsProducts fp ON fp.ProductId = p.Id
JOIN Flags f ON fp.FlagId = f.id
GROUP BY p.Id
这会让你得到像这样的行:
+-------------------------------+-------+-------+---------------------+
| id | title | price | flags |
+-------------------------------+-------+-------+---------------------+
| 00c8234d71c4e94f725cd432ebc04 | Alpha | 589 | Sellout,Top product |
| 018357657529fef056cf396626812 | Beta | 355 | Discount |
| 01a2c32ceeff0fc6b7dd4fc4302ab | Gamma | 0 | Discount |
+-------------------------------+-------+-------+---------------------+
使用 Logstash 过滤器,然后您可以将 flags
拆分成一个数组,您就可以开始了。