如何设置具有多个实体绑定的 ElasticSearch 索引结构
Posted
技术标签:
【中文标题】如何设置具有多个实体绑定的 ElasticSearch 索引结构【英文标题】:How to setup ElasticSearch index structure with multiple entity bindings 【发布时间】:2016-08-23 06:18:11 【问题描述】:最近,我开始在使用 mysql 的 php 编写的遗留电子商务应用程序中实现 ElasticSearch (ES)。我对所有这些东西完全陌生,阅读文档很好,但我真的需要有经验的人给我建议。
从 ES 文档中,我能够设置一个新集群,并且我还发现河流已被弃用并且应该被替换,因此我将它们替换为 Logstash 和 JDBC MySQL 连接器。
此时我有:
弹性搜索 Logstash JDBC MySQL 驱动程序 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 完全是一场灾难(但我现在必须处理它们)。一开始我以为我应该对ES做一个扁平结构的Products索引,但是多实体绑定呢?
【问题讨论】:
如果你想将你的mysql数据移动到ES:sysadminci.wordpress.com/2016/01/06/… 扁平数据结构似乎是迄今为止最好的方法。您对此索引有什么特殊的查询要求吗?考虑 ES 中的数据结构意味着也要考虑要使用的查询。 @falnyr,您在过去 7 天内没有就您的问题发表意见。您还需要更多信息吗? 对不起各位,只是在处理一些其他的东西 atm,我会尽快设置它,以便我看看有什么不清楚的地方。 【参考方案1】:这是一个很好的开始!
我肯定会将其全部展平(即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
拆分为一个数组,一切顺利。
【讨论】:
这是否意味着“标志”映射应该是数组而不是字符串,因为我应用了 logstash 过滤器? String 没问题,ES 会为你创建一个字符串数组。以上是关于如何设置具有多个实体绑定的 ElasticSearch 索引结构的主要内容,如果未能解决你的问题,请参考以下文章
NestJS + MySQL:如何在不设置实体的情况下连接多个数据库
实体框架 - 具有挑战性的设置包括多个主键,以及与外部表的多个关联