本文已参与「新人创作礼」活动,一起开启掘金创作之路。
近期在工作中需要使用es进行简单的全文检索,所以最近都在边学边做笔记,也会把自己遇到的bug以及如何解决的,一并记录在这里,供大家学习参考。
1、概述
在ElsaticSearch的实战过程中,会遇到嵌套文档的形式,这个时候就涉及到nested嵌套类型。
nested类型是一种特殊的对象object数据类型,允许对象数组彼此独立的进行索引和查询。
内部对象object字段的数组不能像我们所期望的那样工作。 Lucene没有内部对象的概念,所以Elasticsearch将对象层次结构扁平化为一个字段名称和值的简单列表。
如果需要索引对象数组并维护数组中每个对象的独立性,则应使用nested数据类型而不是object数据类型。 在内部,嵌套对象将数组中的每个对象作为单独的隐藏文档进行索引,这意味着每个嵌套对象都可以使用嵌套查询nested query独立于其他对象进行查询
2、对象类型
ElasticSearch支持对象类型的存储,我们可以把一个对象数组存放到某个document的字段内。比如把订单当作doc,添加goods字段,存储该订单包含的商品。
PUT /test_order
{
"mappings": {
"properties": {
"orderId" : {
"type" : "long"
},
"createdTime" : {
"type" : "date",
"format" : "yyyy-MM-dd"
},
"userName" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"goodDoc" : {
"type" : "nested",
"properties" : {
"goodName" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"desc" : {
"type" : "text",
"analyzer" : "ik_max_word",
"search_analyzer" : "ik_smart"
},
"nums" : {
"type" : "long"
},
"price" : {
"type" : "long"
}
}
}
}
}
}
向索引中添加两组数据
{
"took" : 533,
"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_order",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"orderId" : 100001,
"createdTime" : "2022-05-11",
"userName" : "用户1",
"goodDoc" : [
{
"goodName" : "乐事薯片",
"desc" : "乐事薯片-番茄风味",
"nums" : 2,
"price" : 15
},
{
"goodName" : "瓜子",
"desc" : "洽洽香瓜子",
"nums" : 2,
"price" : 28
}
]
}
},
{
"_index" : "test_order",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"orderId" : 100002,
"createdTime" : "2022-05-11",
"userName" : "用户2",
"goodDoc" : [
{
"goodName" : "麻花",
"desc" : "黑芝麻味小麻花",
"nums" : 3,
"price" : 18
},
{
"goodName" : "麦片",
"desc" : "奇亚籽水果麦片",
"nums" : 5,
"price" : 49
}
]
}
}
]
}
}
使用查询语句对索引进项查询。
1、查询订单号为100001的订单:
GET /test_order/_search
{
"query": {
"match": {
"orderId": 100001
}
}
}
查询结果:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "test_order",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"orderId" : 100001,
"createdTime" : "2022-05-11",
"userName" : "用户1",
"goodDoc" : [
{
"goodName" : "乐事薯片",
"desc" : "乐事薯片-番茄风味",
"nums" : 2,
"price" : 15
},
{
"goodName" : "瓜子",
"desc" : "洽洽香瓜子",
"nums" : 2,
"price" : 28
}
]
}
}
]
}
}
2、nested类型的查询:
GET /test_order/_search
{
"query": {
"nested": {
"path": "goodDoc",
"query": {
"match": {
"goodDoc.goodName": {
"query": "麻花"
}
}
}
}
}
}
查询结果:
{
"took" : 27,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 2.622515,
"hits" : [
{
"_index" : "test_order",
"_type" : "_doc",
"_id" : "2",
"_score" : 2.622515,
"_source" : {
"orderId" : 100002,
"createdTime" : "2022-05-11",
"userName" : "用户2",
"goodDoc" : [
{
"goodName" : "麻花",
"desc" : "黑芝麻味小麻花",
"nums" : 3,
"price" : 18
},
{
"goodName" : "麦片",
"desc" : "奇亚籽水果麦片",
"nums" : 5,
"price" : 49
}
]
}
}
]
}
}