首页 > 学院 > 开发设计 > 正文

建模数据(一 处理关系集数据)

2019-11-08 20:48:49
字体:
来源:转载
供稿:网友

应用级的Join操作(application-side Join)

我们可以(部分)在应用中模拟关系数据库的join操作。例如,索引 users 和他们的 blog 文章。在关系世界中,我们会这样做:

PUT /my_index/user/1 (1){ "name": "John Smith", "email": "john@smith.com", "dob": "1970/10/24"}PUT /my_index/blogpost/2(1) { "title": "Relationships", "body": "It's complicated...", "user": 1 (2)}

(1)每一个文档由index, type, and id 通过组成了主键。 (2)blogpost 通过存储 userid 来关联 user,而这里不需要指定 *indextype 是因为在我们的应用中它们是被硬编码的。

通过查询 ID为1的user 将很容易找到对应的 blog:

GET /my_index/blogpost/_search{ "query": { "filtered": { "filter": { "term": { "user": 1 } } } }}

为了找到与user中为john相关的博客,我们需要执行两次查询:第一次需要在user中找到名叫johnID列表,第二次将ID列表作为查询参数来执行类似上面的查询:

GET /my_index/user/_search{ "query": { "match": { "name": "John" } }}GET /my_index/blogpost/_search{ "query": { "filtered": { "filter": { "terms": { "user": [1] } (1) } } }}

(1) terms filter 中的值设置未第一次查询中的结果,即ID列表。 应用级别模仿join操作的最大好处是数据是立体的(normalized),如果想改变 user 的姓名,那么只要在 user 这个 document 上改就可以了。而缺点是你必须在查询期间运行额外的 query 来实现 join 的操作。

在这个例子当中,只有一个 user 符合我们的第一个查询条件,但在真实的世界中,很可能会出现数百万人的名字叫 John,将这么多的ID塞到第二个查询中,将会让这个查询语句变得非常庞大,并且这个查询会执行数百万次 term 的查找。

这种模仿join操作的方法适合于前置查询结果集(在该例子中指代 user)比较小,并且最好是不经常变化的,此时我们在应用中可以去缓存这部分数据,避免频繁的执行第一个查询。

参考: [1]https://www.elastic.co/guide/en/elasticsearch/guide/current/application-joins.html#application-joins [2]https://es.xiaoleilu.com/400_Relationships/15_Application_joins.html


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表