第一次接触es,感觉啥啥都是懵逼状态,不得不吐槽一下,出了问题网上写的那些文章真的是看不懂,要么代码不全,要么就是各种抄,根本结局不了问题,还是决定自己写一个吧,没准哪天就帮别人节省了时间.
话不多说,这里使用的版本是7.12.1,查看es版本方法:
直接在浏览器访问es端口号就行 ps:搞了一天才发现看的是2.0的api 我吐了
博主现在查看的api是7.14版本的(直接看最新的了)
为什么要用nested嵌套结构呢?具体可以看官网的解释,这里就不在多做赘述了:
https://www.elastic.co/guide/en/elasticsearch/reference/7.14/nested.html
简单来说就是需要一个多层嵌套的对象结构,例如:
公司下面有部门员工,员工下面有所属项目,都是一对多的关系,后面的代码也是使用的这个逻辑(可能有点不太合理,但是大致是这么个意思)
公司:
____部门名称
____部门员工:
________id
________姓名
________年龄
________所属项目:
____________项目名称
直接上代码
1.声明结构
PUT localhost:9200/test_mapping7{
"mappings": {
"properties":{
"group": {
"type": "text"},"user":{
"type": "nested", //嵌套类型type应为nested"properties":{
"id": {
"type": "keyword"},"name":{
"type": "text"},"age":{
"type": "short"},"project":{
"type": "nested","properties":{
"name": {
"type": "text"}}}}}} }
}
nested类型结构的属性应用properties表示,以下是官网api
2.声明成功后我们可以查询一下声明的结构
GET localhost:9200/test_mapping7?pretty //pretty是输出json格式化后的数据{
"test_mapping7" : {
"aliases" : {
}, "mappings" : {
"properties" : {
"group" : {
"type" : "text" }, "user" : {
"type" : "nested", "properties" : {
"age" : {
"type" : "short" }, "id" : {
"type" : "keyword" }, "name" : {
"type" : "text" }, "project" : {
"type" : "nested", "properties" : {
"name" : {
"type" : "text" } } } } } } }, "settings" : {
"index" : {
"routing" : {
"allocation" : {
"include" : {
"_tier_preference" : "data_content"} } }, "number_of_shards" : "1", "provided_name" : "test_mapping7", "creation_date" : "1630464120543", "number_of_replicas" : "1", "uuid" : "stKB9OdESUmnqJwBKOK-pQ", "version" : {
"created" : "7120199" } } } }
}
3.插入数据
重点: 插入数据这块必须在index名后面加上/_doc/ , 本身这里应该是设置type的字段,但是在实际插入数据时,用自定义的stu,class等都会报错,难道只能插入doc类型? ps:正常猜想是在mapping中没有设置最外层的type,但是实际操作时声明type会报错
POST localhost:9200/test_mapping7/_doc/1 {
"group": "研发","user":[{
"id": 1,"name": "zhangsan","age": 12,"project":[{
"name": "pro1"}]},{
"id": 2,"name": "lisi","age": 15,"project":[{
"name": "pro12"}]}]
}result:{
"_index": "test_mapping7","_type": "_doc","_id": "2","_version": 1,"result": "created","_shards": {
"total": 1,"successful": 1,"failed": 0},"_seq_no": 1,"_primary_term": 1
}
再插入一条
POST localhost:9200/test_mapping7/_doc/2{
"group": "市场","user":[{
"id": 3,"name": "xiaomei","age": 21,"project":[{
"name": "pro3"}]},{
"id": 4,"name": "xiaoxue","age": 25,"project":[{
"name": "pro4"}]}]
}result:{
"_index": "test_mapping7","_type": "_doc","_id": "2","_version": 1,"result": "created","_shards": {
"total": 2,"successful": 1,"failed": 0},"_seq_no": 1,"_primary_term": 1
}
查询一下插入的数据
GET localhost:9200/test_mapping7/_search?pretty{
"took" : 3, "timed_out" : false, "_shards" : {
"total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : {
"total" : {
"value" : 2, "relation" : "eq" }, "max_score" : 1.0, "hits" : [ {
"_index" : "test_mapping7", "_type" : "_doc", "_id" : "1", "_score" : 1.0, "_source" : {
"group" : "研发", "user" : [ {
"id" : 1, "name" : "zhangsan", "age" : 12, "project" : [ {
"name" : "pro1" } ] }, {
"id" : 2, "name" : "lisi", "age" : 14, "project" : [ {
"name" : "pro12" } ] } ] } }, {
"_index" : "test_mapping7", "_type" : "_doc", "_id" : "2", "_score" : 1.0, "_source" : {
"group" : "市场", "user" : [ {
"id" : 3, "name" : "xiaomei", "age" : 21, "project" : [ {
"name" : "pro3" } ] }, {
"id" : 4, "name" : "xiaoxue", "age" : 25, "project" : [ {
"name" : "pro4" } ] } ] } } ] }
}
4.查询
首先查询一下name=zhangsan的index
GET localhost:9200/test_mapping7/_search{
"query": {
"nested":{
"path": "user","query": {
"bool":{
"must": [{
"match": {
"user.name":"zhangsan"}}]}}}}
}result:{
"took": 2,"timed_out": false,"_shards": {
"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {
"total": {
"value": 1,"relation": "eq"},"max_score": 1.2039728,"hits": [{
"_index": "test_mapping7","_type": "_doc","_id": "1","_score": 1.2039728,"_source": {
"group": "研发","user": [{
"id": 1,"name": "zhangsan","age": 12,"project": [{
"name": "pro1"}]},{
"id": 2,"name": "lisi","age": 14,"project": [{
"name": "pro12"}]}]}}]}
}
可以看到直接返回了整个doc1对象,符合预期结果
那么我们如果查询条件是project.name=pro4呢?划重点
nested.path必须是从外层开始写: user.project,不可以直接写project
match条件也要从最外层开始写 user.project.name=pro4,不可以直接写project.name=pro4
POST localhost:9200/test_mapping7/_search{
"query": {
"nested":{
"path": "user.project","query": {
"bool":{
"must": [{
"match": {
"user.project.name":"pro4"}}]}}}}
}result:{
"took": 2,"timed_out": false,"_shards": {
"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {
"total": {
"value": 1,"relation": "eq"},"max_score": 1.2039728,"hits": [{
"_index": "test_mapping7","_type": "_doc","_id": "2","_score": 1.2039728,"_source": {
"group": "市场","user": [{
"id": 3,"name": "xiaomei","age": 21,"project": [{
"name": "pro3"}]},{
"id": 4,"name": "xiaoxue","age": 25,"project": [{
"name": "pro4"}]}]}}]}
}
成功命中
未完待续,欢迎补充指正