第一次接触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",
"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
{
"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类型?
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"
}
]
}
]
}
}
]
}
}
成功命中 未完待续,欢迎补充指正
|