ES实现三表关联查询+条件过滤

这篇具有很好参考价值的文章主要介绍了ES实现三表关联查询+条件过滤。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

需求背景

        很多时候mysql的表之间是一对多的关系,比如库信息表(元数据信息),表信息表(元数据信息),字段信息表(元数据信息)。一个库可以包含多个表,一个表可以包含多个字段。他们的关系:库—(1:n)->表—(1:n)->字段。

        ElasticsSearch(以下简称ES)处理这种关系虽然不是特别擅长(相对于关系型数据库),因为ES和大多数 NoSQL 数据库类似,是扁平化的存储结构。索引是独立文档的集合体。不同的索引之间一般是没有关系的。

不过ES目前毕竟发展到8.x版本了, 已经有几种可选的方式能够高效的支持这种一对多关系的映射。

        比较常用的方案是嵌套对象,嵌套文档和父子文档。后两种是我们本文要讲的内容。

表结构

        为了便于描述下面的demo内容,现在先介绍一下表结构demo内容(表名称:字段1,字段2,字段3......)

database: database_id, name, desc

table:table_id,name,desc,address

column:column_id,name,desc,address文章来源地址https://www.toymoban.com/news/detail-755100.html

嵌套文档查询实例

#建立索引元数据:两层嵌套 database->table->column
put http://localhost:9200/test_nested
{
	"mappings": {
		"properties": {
			"table": {
				"type": "nested",
				"properties": {
					"column": {
						"type": "nested" 
					}
				}
		 
			}
		}
	}
}
#创建1个库数据database1
PUT http://localhost:9200/test_nested/_doc/database1
{
	"database_id": 1,
	"name" : "database1",
	"des" : "This is a database!",
	"table" : [
		{
		  "table_id":1,
		  "name" : "John",
		  "des" :  "This is a table!",
		  "address":"hangzhou",
		  "column":[
				{
					"column_id":1,
					"name" :"zhangsan",
					"des" :  "This is a column!",
					"address":"wuhan"
				},
				{
					"column_id":2,
					"name" :"Alice",
					"des" :  "This is a column!",	
					"address":"changchun"
				}
			]
		},
		{
		  "table_id":2,
		  "name" : "Alice",
		  "des" :  "This is a table!",
		  "address":"changchun",
		  "column":[
				{
					"column_id":3,
					"name" :"zhangsan",
					"des" :  "This is a column!",	
					"address":"hangzhou"
				},
				{
					"column_id":4,
					"name" :"John",
					"des" :  "This is a column!",	
					"address":"zhengzhou"
				}
			]
		}
	]
}

#创建1个库数据database2
PUT http://localhost:9200/test_nested/_doc/database2
{
	"database_id": 2,
	"name" : "database2",
	"des" : "This is a database!",
	"table" : [
		{
		  "table_id":3,
		  "name" : "zhangsan",
		  "des" :  "This is a table!",
		  "address":"wuhan",
		  "column":[
				{
					"column_id":5,
					"name" :"John",
					"des" :  "This is a column!",
					"address":"hangzhou"
				},
				{
					"column_id":6,
					"name" :"Alice",
					"des" :  "This is a column!",	
					"address":"changchun"
				}
			]
		},
		{
		  "table_id":4,
		  "name" : "Alice",
		  "des" :  "This is a table!",
		  "address":"changchun",
		  "column":[
				{
					"column_id":7,
					"name" :"zhangsan",
					"des" :  "This is a column!",	
					"address":"hangzhou"
				},
				{
					"column_id":8,
					"name" :"John",
					"des" :  "This is a column!",	
					"address":"zhengzhou"
				}
			]
		}
	]
}

#嵌套查询例子,查询column匹配指定内容,且table匹配指定内容的文档
POST http://localhost:9200/test_nested/_search
{
	"query" : {
		"bool": {
			"must": [ 
				{
					"nested": {
						"path": "table",
						"query": {
							"bool": {
								"must": [
									{ 
										"match": { 
											"table.address": "hangzhou" 
										}
									},
									{ 
										"match": { 
											"table.name": "John" 
										}
									}
								]
							}
						}
					}
				},
				{
					"nested": {
						"path": "table.column",
						"query" : {
							"bool": {
								"must": [
									{ 
										"match": { 
											"table.column.address": "wuhan" 
										}
									},
									{ 
										"match": { 
											"table.column.name": "zhangsan" 
										}
									}
								 ]
							}

						}
					}
				}
			]
		}
	}
}

#实现类似"三表关联查询+条件过滤",查询cloumn匹配指定内容,或table匹配指定内容,或database匹配指定内容的文档
POST http://localhost:9200/test_nested/_search
{
	"query" : {
		"bool": {
			"should": [ 
				{
					"nested": {
						"path": "table",
						"query": {
							"bool": {
								"must": [
									{ 
										"match": { 
											"table.address": "hangzhou" 
										}
									},
									{ 
										"match": { 
											"table.name": "John" 
										}
									}
								]
							}
						}
					}
				},
				{
					"nested": {
						"path": "table.column",
						"query" : {
							"bool": {
								"must": [
									{ 
										"match": { 
											"table.column.address": "hangzhou" 
										}
									},
									{ 
										"match": { 
											"table.column.name": "John" 
										}
									}
								 ]
							}

						}
					}
				},
				{
					"match" :{
						"name":"hangzhou"
					}
				}
			]
		}
	}
}

父子文档查询实例

#创建索引元数据
put http://localhost:9200/metadata1
{
  "mappings": {
    "properties": {
      "my_join_field": {
        "type": "join",
        "relations": {
          "database": ["table"],
          "table": ["column"]
        }
      }
    }
  }
}

#创建1个父文档
put http://localhost:9200/metadata1/_doc/1
{
  "database_id": "1",
  "des": "This is a database!",
  "name":"zhangsan",
  "address":"hangzhou",
  "my_join_field": {
    "name": "database" 
  }
}

#创建1个子文档
put http://localhost:9200/metadata1/_doc/2?routing=1
{
  "table_id": "1",
  "des": "This is a table!",
  "name":"lisi",
  "address":"hangzhou",
  "my_join_field": {
    "name": "table",
	"parent":1
  }
}

#创建1个孙子文档
put http://localhost:9200/metadata1/_doc/3?routing=2
{
  "column_id": "1",
  "des": "This is a column!",
  "name":"wangwu",
  "address":"hangzhou",
  "my_join_field": {
    "name": "column",
	"parent":2
  }
}

#创建1个孙子文档
put http://localhost:9200/metadata1/_doc/4?routing=2
{
  "column_id": "2",
  "des": "This is a column!",
  "name":"hangzhou",
  "address":"zhengzhou",
  "my_join_field": {
    "name": "column",
	"parent":2
  }
}

#创建1个孙子文档,用于验证查询内容默认分词了
put http://localhost:9200/metadata1/_doc/5?routing=2
{
  "column_id": "3",
  "des": "This is a column!",
  "name":"hangzhouren",
  "address":"hangzhou city",
  "my_join_field": {
    "name": "column",
	"parent":2
  }
}

#分页查询某个字段(查询范围包括父,子,孙子文档)
post http://localhost:9200/metadata1/_search
{
  "query" : {
		"match": {
			"address" : "hangzhou"
		}
	},
	"from" : 1,
	"size" : 1
}

#term 批量查询
post http://localhost:9200/metadata1/_search
{
	"query": {
		"terms" : {
			"address":["hangzhou pro","zhengzhou"]
		}
	}
}

#查询具备满足匹配内容的孙子文档的子文档
post http://localhost:9200/metadata1/_search
{
  "query": {
    "has_child": {
      "type": "column",
      "query" : {
			"match": {
				"address" : "hangzhou"
			}
		}
    }
  }
}

#查询具备满足匹配内容的子文档的父文档
post http://localhost:9200/metadata1/_search
{
  "query": {
    "has_child": {
      "type": "table",
      "query" : {
			"match": {
				"address" : "hangzhou"
			}
		}
    }
  }
}

#查询具备满足匹配内容的孙子文档的父文档
post http://localhost:9200/metadata1/_search
{
  "query": {
    "has_child": {
      "type": "table",
      "query" : {
			"has_child": {
				"type": "column",
				"query" : {
					"multi_match": {
						"query" : "hangzhou",
						"fields":["address","name"]
					}
				}
			}
		}
    }
  }
}

#bool查询满足条件孙子文档的父文档,和满足条件子文档的父文档
post http://localhost:9200/metadata1/_search
{
	"query": {
		"bool": {
			"should": [
				{
					"has_child": {
					  "type": "table",
					  "query" : {
							"has_child": {
								"type": "column",
								"query" : {
									"multi_match": {
										"query" : "hangzhou",
										"fields":["address","name"]
									}
								}
							}
						}
					}
				},
				{
					"has_child": {
						"type": "table",
						"query" : {
							"multi_match": {
								"query" : "hangzhou",
								"fields":["address","name"]
							}
						}
					}
				}
			]
		}
	}	
	 
}

#查询满足条件子文档的父文档的子文档,即子文档本身;如果父,子,孙文档的文档字段名称不同,就不用这么麻烦的查询
post http://localhost:9200/metadata1/_search
{
	"query": {
		"has_parent": {
			"parent_type": "database",
			"query" : {
				"has_child": {
					"type": "table",
					"query" : {
						"multi_match": {
							"query" : "hangzhou",
							"fields":["address","name"]
						}
					}
				}
			}

		}
	}	
	 
}


#以下两条查询可以类似实现"三表关联查询+条件过滤"的功能
#先查询满足条件匹配的父文档的子文档,满足条件匹配孙子文档的子文档和满足条件匹配的子文档
post http://localhost:9200/metadata1/_search
{
	"query": {
		"bool": {
			"should": [
				{
					"has_parent": {
					  "parent_type": "database",
							"query" : {
								"multi_match": {
									"query" : "hangzhou",
									"fields":["address","name"]
								}
							}
					}
				},
				{
					"has_child": {
						"type": "column",
						"query" : {
							"multi_match": {
								"query" : "hangzhou",
								"fields":["address","name"]
							}
						}
					}
				},
				{
					"has_parent": {
						"parent_type": "database",
						"query" : {
							"has_child": {
								"type": "table",
								"query" : {
									"multi_match": {
										"query" : "hangzhou",
										"fields":["address","name"]
									}
								}
							}
						}

					}
				}
			]
		}
	}	
	 
}

#根据上面的子文档查询关联的父文档和孙子文档,然后再在程序里进行数据关联组装
post http://localhost:9200/metadata1/_search
{
	"query": {
		"bool": {
			"should": [
				{
					"has_parent": {
					  "parent_type": "table",
							"query" : {
								"ids": {
									"values" : [2]
								}
							}
					}
				},
				{
					"has_child": {
						"type": "table",
						"query" : {
							"ids": {
									"values" : [2]
								}
						}
					}
				}
			]
		}
	}	
	 
}


到了这里,关于ES实现三表关联查询+条件过滤的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ES7 and or 关联条件查询JAVA

    @ES7 and or 关联条件查询JAVA 实现条件( platform=‘xxx’ and (home_path=‘xxx’ or nick_name=‘xxx’ )) kibana

    2024年02月08日
    浏览(38)
  • ElasticSearch第十四讲 ES有条件复杂查询

    模糊匹配 模糊匹配主要是针对文本类型的字段,文本类型的字段会对内容进行分词,对查询时,也会对搜索条件进行分词,然后通过倒排索引查找到匹配的数据,模糊匹配主要通过match等参数来实现 match : 通过match模糊匹配条件内容 prefix : 前缀匹配 regexp : 通过正则表达

    2024年02月03日
    浏览(38)
  • ElasticSearch系列 - SpringBoot整合ES:组合多个查询条件 bool 查询

    01. ElasticSearch 布尔查询是什么? 在实际应用中,我们很有可能会查询多个值或字段。 一个 bool 查询由三部分组成: must:所有的语句都必须(must) 匹配,与 AND 等价。 must_not:所有的语句都不能(must not)匹配,与 NOT 等价。 should:至少有一个语句要匹配,与 OR 等价。 02.

    2023年04月08日
    浏览(57)
  • 【Elasticsearch】ES查询出满足以下其中任意一个条件的订单

    需求:最近测试经理给我这边提出一个需求,大致可以描述为查询出\\\" 购买的商品名称中包含’测试’ “、” 订单的收货地址包含’B360’ \\\"、“收货人手机号为测试人员的手机号”; 一、实现方案 当时评估了两种方案: ①、直接从数据库中查询; ②、从ES中查询; 方案①

    2024年02月16日
    浏览(28)
  • sql语句转为es查询条件(elasticsearch-sql使用)

    github源码地址: https://gitee.com/weiyxiong_admin/elasticsearch-sql/blob/master/src/test/java/org/nlpcn/es4sql/ExplainTest.java 1、添加pom.xml依赖 2、scala 将sql转为es查询json语句 3、测试 4、查询返回结果展示(即步骤三esJSON结果打印) 5、打开postman

    2024年02月13日
    浏览(44)
  • java 整合ES实现文档增删改查(多条件分页查询)

    本文采用ES版本为8.7.1 由于只存储文章,仅用固定索引即可,索引用kibanna直接生成,省略索引部分的增删查步骤 抓取返回信息是因为版本问题无法解析ES返回的正确信息,实际操作成功但是会报错 我这边只需要单索引操作,有需求的可以让前端传过来

    2024年02月13日
    浏览(29)
  • 【elasticsearch】ES去重查询实现

    去重实现原理: 采用es 的Collapse折叠+cardinality基数计算 实现去重 1、优点:简单快速效率高,几乎无性能损耗(相比于分桶去重) 2、缺点: 1)Collapse折叠只支持一个字段去重,且字段必须是 keyword 2)cardinality基数计算去重后数量 (采用hyperloglog实现,hyperloglog一种近似计算)

    2024年02月06日
    浏览(32)
  • ES(Elasticsearch)+SpringBoot实现分页查询

    1.ES介绍   ES作为一个搜索工具,寄托于Lucene之上,提供了方便的数据存储和搜索服务,一般的用它来作为网页数据索引以及存储用户画像(即用户标签)数据,可以提供复具有复杂的查询条件的服务。例如在网页索引中,通过倒排的方式索引的方式,对文档进行分词存储,

    2024年02月16日
    浏览(37)
  • ElasticSearch入门:使用ES来实现模糊查询功能

    本文针对在工作中遇到的需求:通过es来实现 模糊查询 来进行总结;模糊查询的具体需求是:查询基金/A股/港股等金融数据,要求可以根据 字段 , 拼音首字母 , 部分拼音全称 进行联想查询;需要注意的是,金融数据名称中可能不止包含汉字,还有英文,数字,特殊字符等

    2023年04月09日
    浏览(37)
  • ES多条件查询

    场景:想要查询出设备id 为 3 的所有设备上报信息,并且上报信息的开始时间或结束时间只要有一个满足 在 某个时间段里即可。 在 Elasticsearch 中,您可以使用布尔查询来实现同时满足条件1并且满足条件2或条件3中的一个的查询。具体来说,您可以使用“must”子句来指定满足

    2024年02月09日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包