在es内部 arrays,会被做一些特殊处理,当使用对象类型的arrays时,会造成无法使用对象的多个字段精确定位。

    想要解决这个问题,可以使用nested类型解决这个问题

 

 

arrays相关操作:

        这里我们假设,现在有一个需求,需要记录选修课中,选择某一个老师的学生有哪些。

 

创建索引

curl -XPUT "localhost:9200/test_arrays"

 

为索引创建mapping

curl -XPUT -H "Content-Type: application/json"  "127.0.0.1:9200/test_arrays/_mapping/class" -d'
{
    "properties":{
            "id":{
                "type":"keyword"
            },
            "name":{
                "type":"text"
            },
            "student":{                     #定义数组类型数据
                "properties":{             #以下开始定义数组里每一个字段的类型
                    "name":{
                        "type":"text"
                    },
                    "id":{
                        "type":"keyword"
                    }
                }
            }
    }
}'

 

向索引中添加数据(以数组形式添加)

curl -XPOST -H "Content-Type: application/json"  "127.0.0.1:9200/test_arrays/class" -d'
{
    "id": "1",
    "name":  "Mr Li",
    "student":[{
            "name": "li wu",
            "id": "001"
        },{
            "name": "li si",
            "id": "002"
        }
    ]
}'

普通添加数据

curl -XPOST -H "Content-Type: application/json"  "127.0.0.1:9200/test_arrays/class" -d'
{
    "id": "1",
    "name":  "Mr Li",
    "student":{
            "name": "li san",
            "id": "003"
    }
}'

 

查看索引中文档数:

[root@jiangmin ~]# curl  "127.0.0.1:9200/_cat/indices?v"
    health status index       uuid                   pri rep docs.count docs.deleted store.size pri.store.size
    yellow open   test_arrays YRxATOUES4GkbPDlVXSaHQ   5   1          2            0      8.5kb          8.5kb
    yellow open   kvdata      NHXm9V03Rh6LlRmYKxlR6A   5   1         15            0     60.1kb         60.1kb
    yellow open   twitter     A_QiT7VoQbOBWlbql365rQ   5   1          2            0      9.6kb          9.6kb

    由此可知,添加两次数据,对应两个文档,es中数据以文档形式添加

 

根据学生id查询

curl -XGET -H "Content-Type: application/json"  "127.0.0.1:9200/test_arrays/class/_search" -d'
{
    "query":{
        "bool":{            #指明为布尔查询,可允许再单独的查询中组合任意数量的查询
            "must":{       #布尔查询的三个条件之一,must表明接下来的查询条件是必须符合的
                "match":{
                    "student.id":"001"
                }
            }
        }
    }
}'

查询结果

{"took":3,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":1,"max_score":0.2876821,"hits":[{"_index":"test_arrays","_type":"class","_id":"Wxl-VW8B5IaOoVqIepkO","_score":0.2876821,"_source":
{
    "id": "1",
    "name":  "Mr Li",
    "student":[{
            "name": "li wu",
            "id": "001"
        },{
            "name": "li si",
            "id": "002"
        }
    ]
}}]}}[root@jiangmin ~]#

 

根据学生姓名查询

curl -XGET -H "Content-Type: application/json"  "127.0.0.1:9200/test_arrays/class/_search" -d'
{
    "query":{
        "bool":{                #指明为布尔查询,可允许再单独的查询中组合任意数量的查询
            "must":{           #布尔查询的三个条件之一,must表明接下来的查询条件是必须符合的
                "match":{
                    "student.name": "li wu"
                }
            }
        }
    }
}'

查询结果:

{"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":2,"max_score":0.68324494,"hits":[{"_index":"test_arrays","_type":"class","_id":"Wxl-VW8B5IaOoVqIepkO","_score":0.68324494,"_source":
{
    "id": "1",
    "name":  "Mr Li",
    "student":[{
            "name": "li wu",
            "id": "001"
        },{
            "name": "li si",
            "id": "002"
        }
    ]
}},{"_index":"test_arrays","_type":"class","_id":"XBl_VW8B5IaOoVqI75nt","_score":0.2876821,"_source":
{
    "id": "1",
    "name":  "Mr Li",
    "student":{
            "name": "li san",
            "id": "003"
    }
}}]}}[root@jiangmin ~]#

 

 

根据学生姓名和id查询(由arrays引起的错误查询---如果需要解决这个问题使用嵌套对象nested)

curl -XGET -H "Content-Type: application/json"  "127.0.0.1:9200/test_arrays/class/_search" -d'
{
    "query":{
        "bool":{              #指明为布尔查询,可允许再单独的查询中组合任意数量的查询
            "must": [        #布尔查询的三个条件之一,must表明接下来的查询条件是必须符合的
                {
                    "match":{
                        "student.id": "002"
                    }
                },
                {
                    "match":{
                        "student.name": "li wu"
                    }
                }              
            ]
        }
    }
}'

 

获得结果如下:

{"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":1,"max_score":0.970927,"hits":[{"_index":"test_arrays","_type":"class","_id":"Wxl-VW8B5IaOoVqIepkO","_score":0.970927,"_source":
{
    "id": "1",
    "name":  "Mr Li",
    "student":[{
            "name": "li wu",
            "id": "001"
        },{
            "name": "li si",
            "id": "002"
        }
    ]
}}]}}[root@jiangmin ~]#

 

根据之前的操作可知,并不存在学生为002,名字为li wu的学生。 由于数组在存储时,按照如下形式存储。

 "student.id": [ "001", "002", "003"]

 "student.name": ["li wu", "li si", "li san"]

分词的时候,会按照这种顺序,将id和name中的值,随机组合。

数组中的查询条件不能相互组合

这种错误,只有使用nested对象类型才能解决

 

 


 

nested相关操作:

创建索引

curl -XPUT "localhost:9200/test_nested"

 

为索引创建mapping

curl -XPUT -H "Content-Type: application/json"  "127.0.0.1:9200/test_nested/_mapping/class" -d'
{
    "properties":{
            "id":{
                "type":"keyword"
            },
            "name":{
                "type":"text"
            },
            "student":{                     #定义数组类型数据
                "type":"nested",         #定义nested类型
                "properties":{             #以下开始定义数组里每一个字段的类型
                    "name":{
                        "type":"text"
                    },
                    "id":{
                        "type":"keyword"
                    }
                }
            }
    }
}'

 

重复以上操作添加数据:

提交测试数据

curl -XPOST -H "Content-Type: application/json"  "127.0.0.1:9200/test_nested/class" -d'
{
    "id": "1",
    "name":  "Mr Li",
    "student":[{
            "name": "li wu",
            "id": "001"
        },{
            "name": "li si",
            "id": "002"
        }
    ]
}'

 

查询非法数据

curl -XGET -H "Content-Type: application/json"  "127.0.0.1:9200/test_nested/class/_search" -d'
{
    "query":{
        "bool":{             
            "must": [        
                {
                    "match":{
                        "student.id": "002"
                    }
                },
                {
                    "match":{
                        "student.name": "li wu"
                    }
                }              
            ]
        }
    }
}'

获得结果无法查询

{"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}}

 

查询正确数据

 

这个验证有点问题,暂时不做处理,需要说明的是,nested类型的查询操作,与普通的查询操作不一样

 

curl -XGET -H "Content-Type: application/json"  "127.0.0.1:9200/test_nested/class/_search" -d'
{
    "query":{
        "nested":{
            "path":"student",
            "query":{
                    "bool":{             
                        "must": [        
                            {
                                "match":{
                                    "student.id": "002"
                                }
                            },
                            {
                                "match":{
                                    "student.name": "li si"
                                }
                            }              
                        ]
                    }
            }
        }
    }
}'