1、關於對象類型的操作和查詢
創建索引,插入數據
PUT /blog { "mappings": { "properties": { "Content":{ "type": "text" }, "CreateTime":{ "type": "date", "format": "yyyy-MM-dd HH:mm:ss" }, "Author":{ "properties": { "UserName":{ "type":"keyword" }, "Adress": { "type": "text" } } } } } } PUT blog/_doc/1 { "Content":"i learn Elasticsearch", "time":"2020-01-01 00:00:00", "Author":{ "UserName":"mark", "Adress":"hangzhou" } }
現在需要統計作爲爲mark,文章內容爲Elasticsearch的文檔記錄,代碼如下:
GET blog/_search { "query": { "bool": { "must": [ {"match": { "Content": "Elasticsearch" }},{ "match": { "Author.UserName": "mark" } } ] } } }
搜索結果如下:
{ "took" : 0, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 1, "relation" : "eq" }, "max_score" : 0.5753642, "hits" : [ { "_index" : "blog", "_id" : "1", "_score" : 0.5753642, "_source" : { "Content" : "i learn Elasticsearch", "time" : "2020-01-01 00:00:00", "Author" : { "UserName" : "mark", "Adress" : "hangzhou" } } } ] } }
當嵌套對象只有一個時,搜索是正常的,但是注意下面關於2的用法
2、關於對象數組的操作
PUT /blog { "mappings": { "properties": { "Content":{ "type": "text" }, "CreateTime":{ "type": "date", "format": "yyyy-MM-dd HH:mm:ss" }, "Author":{ "properties": { "UserName":{ "type":"keyword" }, "Adress": { "type": "text" } } } } } } PUT blog/_doc/1 { "Content":"i learn Elasticsearch", "time":"2020-01-01 00:00:00", "Author":[ { "UserName":"mark", "Adress":"hangzhou" }, { "UserName":"jerry", "Adress":"shanghai" } ] }
當博客存在兩個作者時,此時需要搜索作者名爲mark,且聯繫地址時shanghai的記錄,顯然是不存在的,代碼如下:
GET blog/_search { "query": { "bool": { "must": [ {"match": { "Author.Adress": "shanghai" }},{ "match": { "Author.UserName": "mark" } } ] } } }
搜索結果如下:
{ "took" : 2, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 1, "relation" : "eq" }, "max_score" : 0.64933956, "hits" : [ { "_index" : "blog", "_id" : "1", "_score" : 0.64933956, "_source" : { "Content" : "i learn Elasticsearch", "time" : "2020-01-01 00:00:00", "Author" : [ { "UserName" : "mark", "Adress" : "hangzhou" }, { "UserName" : "jerry", "Adress" : "shanghai" } ] } } ] } }
此時,存在結果,顯示是不對的.這裏看官方的介紹,當將字段描述成object類型時,存入的數組對象,es會移除對象數組中對象屬性之間的關聯關係,也就是說如下代碼:
{ "UserName" : "mark", "Adress" : "hangzhou" }
es會移除UserName和Adress的關聯關係,彼此是獨立的,從而建立如下關係
{ "Author.Adress" : [ "hangzhou", "shanghai" ], "Author.UserName" : [ "mark", "jerry" ] }
所以失去了關聯關係之後的搜索,只能按照keyvalue的形式進行搜索,從而返回值,所以這裏must查詢可以查詢到結果,所以解決這個問題,只能通過將字段描述成Nested類型
3、Nested類型
3.1 解決object的問題
PUT /blog { "mappings": { "properties": { "Content":{ "type": "text" }, "CreateTime":{ "type": "date", "format": "yyyy-MM-dd HH:mm:ss" }, "Author":{ "type": "nested", "properties": { "UserName":{ "type":"keyword" }, "Adress": { "type": "text" } } } } } } PUT blog/_doc/1 { "Content":"i learn Elasticsearch", "time":"2020-01-01 00:00:00", "Author":[ { "UserName":"mark", "Adress":"hangzhou" }, { "UserName":"jerry", "Adress":"shanghai" } ] }
因爲2中存在的問題,此時將Author描述成Nested類型,在執行如下搜索
GET blog/_search { "query": { "bool": { "must": [ {"match": { "Author.Adress": "shanghai" }},{ "match": { "Author.UserName": "mark" } } ] } } }
結果如下:
{ "took" : 1, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 0, "relation" : "eq" }, "max_score" : null, "hits" : [ ] } }
此時結果正確,Nested類型的文檔會被保存在兩個Lucene文檔中,查詢時做 join 處理
3.2 通過nested實現類似關係型數據庫的join關聯條件限制查詢
查詢文章內容中包含Elasticsearch且作者爲mark的記錄
GET blog/_search { "query": { "bool": { "must": [ { "match": { "Content": "Elasticsearch" } }, { "nested": { "path": "Author", "query": { "bool": { "must": [ { "match": { "Author.UserName": "mark" } } ] } } } } ] } } }
結果如下:
{ "took" : 222, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 1, "relation" : "eq" }, "max_score" : 1.3862944, "hits" : [ { "_index" : "blog", "_id" : "2", "_score" : 1.3862944, "_source" : { "Content" : "i learn Elasticsearch", "time" : "2020-01-01 00:00:00", "Author" : [ { "UserName" : "scott", "Adress" : "newyork" }, { "UserName" : "sam", "Adress" : "english" } ] } } ] } }