Elasticsearch嵌套查詢

2019獨角獸企業重金招聘Python工程師標準>>> hot3.png

一、背景

最近在做基于宴會廳檔期的商戶搜索推薦時,如果用傳統平鋪式的mapping結構,無法滿足需求場景,于是用到了Elasticsearch支持的Nested(嵌套)查詢。

二、普通對象與嵌套對象的索引異同

如果一個對象不是嵌套類型,那么以如下原數據為例:

PUT /my_index/blogpost/1  
{  "title":"Nest eggs",  "body":  "Making your money work...",  "tags":  [ "cash", "shares" ],  "comments":[  {  "name":    "John Smith",  "comment": "Great article",  "age":     28,  "stars":   4,  "date":    "2014-09-01"  },  {  "name":    "Alice White",  "comment": "More like this please",  "age":     31,  "stars":   5,  "date":    "2014-10-22"  }  ]  
}

由于是json格式的結構化文檔,es會平整成索引內的一個簡單鍵值格式,如下:

{  "title":  [ eggs, nest ],  "body":  [ making, money, work, your ],  "tags":    [ cash, shares ],  "comments.name":    [ alice, john, smith, white ],  "comments.comment":  [ article, great, like, more, please, this ],  "comments.age":      [ 28, 31 ],  "comments.stars":     [ 4, 5 ],  "comments.date":      [ 2014-09-01, 2014-10-22 ]  
}

這樣的話,像這種john/28,Alice/31間的關聯性就丟失了,Nested Object就是為了解決這個問題。

將comments指定為Nested類型,如下mapping:

curl -XPUT 'localhost:9200/my_index' -d '  
{  "mappings":{  "blogpost":{  "properties":{  "comments":{  "type":"nested",   //聲明為nested類型"properties":{  "name":    {"type":"string"},  "comment": { "type": "string"},  "age":     { "type": "short"},  "stars":   { "type": "short"},  "date":    { "type": "date"}  }  }  }  }  }  
}

這樣,每一個nested對象將會作為一個隱藏的單獨文本建立索引,進而保持了nested對象的內在關聯關系,如下:

{ ①  "comments.name":    [ john, smith ],  "comments.comment": [ article, great ],  "comments.age":     [ 28 ],  "comments.stars":   [ 4 ],  "comments.date":    [ 2014-09-01 ]  
}  
{   "comments.name":    [ alice, white ],  "comments.comment": [ like,more,please,this],  "comments.age":     [ 31 ],"comments.stars":   [ 5 ],  "comments.date":    [ 2014-10-22 ]  
}  
{   "title":          [ eggs, nest ],  "body":         [ making, money, work, your ],  "tags":          [ cash, shares ]  
}  
①nested object

三、嵌套對象的查詢

命令查詢(輸出結果1):

curl -XGET localhost:9200/yzsshopv1/shop/_search?pretty -d '{"query" : {"bool" : {"filter" : {"nested" : {"path":"hallList","query":{"bool":{"filter":{"term":{"hallList.capacityMin" : "11"}}}}}}}}}'
{"took" : 3,"timed_out" : false,"_shards" : {"total" : 5,"successful" : 5,"failed" : 0},"hits" : {"total" : 1,"max_score" : 0.0,"hits" : [ {"_index" : "yzsshopv1","_type" : "shop","_id" : "89999988","_score" : 0.0,"_source" : {"cityId" : "1","shopName" : "xxxx婚宴(yyyy店)","shopId" : "89999988","categoryId" : [ "55", "165", "2738" ],"hallList" : [ {"hallId" : "20625","schedule" : ["2017-11-10", "2017-11-09"],"capacityMax" : 16,"capacityMin" : 12},  {"hallId" : "21080","schedule" : [ "2017-12-10", "2017-09-09",  "2017-02-25"],"capacityMax" : 20,"capacityMin" : 11} ],"wedHotelTagValue" : [ "12087", "9601", "9603", "9602" ],"regionId" : [ "9", "824" ]}} ]}
}

java api查詢封裝:

BoolQueryBuilder boolBuilder = new BoolQueryBuilder();
NestedQueryBuilder nestedQuery = new NestedQueryBuilder("hallList", new TermQueryBuilder("hallList.capacityMin","11"));   //注意:除path之外,fieldName也要帶上path (hallList)boolBuilder.filter(nestedQuery);
searchRequest.setQuery(boolBuilder); //設置查詢條件

java api輸出字段封裝:

searchRequest.addField("shopId");
searchRequest.addField("hallList. schedule");
searchRequest.addField("hallList.capacityMin");
searchRequest.addField("hallList.capacityMax");

如果輸出的outputField為searchRequest.addField("hallList"),則會報錯:illegal_argument_exception,reason:field [hallList] isn't a leaf field;

如果輸出的outputField為searchRequest.addField("capacityMin"),則不報錯,但沒有capacityMin字段的值;

正確調用search后的輸出結果(輸出結果2):

{"took" : 8,"timed_out" : false,"_shards" : {"total" : 5,"successful" : 5,"failed" : 0},"hits" : {"total" : 1,"max_score" : 0.0,"hits" : [{"_index" : "yzsshopv1","_type" : "shop","_id" : "89999988","_score" : 0.0,"fields" : {"shopId" : [ "89999988" ],"hallList.hallId" : [ "20625", "21080"],"hallList.capacityMin" : [12, 11 ],"hallList.capacityMax" : [16, 20 ],"hallList.schedule" : [ "2017-11-10", "2017-11-09",  "2017-12-10", "2017-09-09",  "2017-02-25"]}}]}
}

對比輸出結果1和2發現,命令輸出嵌套對象結果1沒問題,但通過java api輸出結果2時,嵌套對象內部的關系也會打亂,比如hallList.schedule字段,無法區分到底哪些值屬于hallList.hallId-20625,哪些屬于21080。

//============以下更新20170331===========

經過后續調試,發現要讓java api輸出正確結果的嵌套對象,不能通過searchRequest.addField的方式,因為嵌套對象并不是葉子節點,需要通過以下的方式添加輸出字段:

searchRequest.setFetchSource(new String[]{"shopId","hallList"},new String[]{});

還有一個不足點是: 嵌套查詢請求返回的是整個文本,而不僅是匹配的nested文本。

四、參考文檔

  1. https://www.elastic.co/guide/en/elasticsearch/guide/master/nested-objects.html
  2. http://stackoverflow.com/questions/23562192/unable-to-retrieve-nested-objects-using-elasticsearch-java-api
  3. http://elasticsearch.cn/book/elasticsearch_definitive_guide_2.x/nested-aggregation.html

轉載于:https://my.oschina.net/weiweiblog/blog/1572727

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/279639.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/279639.shtml
英文地址,請注明出處:http://en.pswp.cn/news/279639.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

寫給深圳首期Python自動化開發周未班的信

你是否做了正確的決定? 深圳首期周未班的同學們大家好,我是Alex, 老男孩教育的聯合創始人,Python項目的發起人,51CTO學院連續2屆最受學員喜愛的講師,中國最早一批使用Python的程序員,當然還有一堆頭銜&…

網站跳出率的相關要點介紹

今天小峰seo博客和大家一起來探討關于“網站跳出率的相關要點”,這里大體是分為三大要點:首先是進入的流量渠道,然后就是綜合流量速度和內容的質量問題,細的來說就是我們的網站進來的用戶是搜索什么關鍵詞來的是通過百度還是搜狗或…

如何使用PowerShell提升開發效率(以Windows Embedded CE為例)

簡介 本文講述如何使用Powershell通過RAPI來控制Windows Embedded CE和Windows Mobile設備。 緣由 我入行的時候是做AS400 RPG和UNIX C開發的,所有開發環境都是字符界面,因此習慣了vigrepmake的開發模式。后來開始做Windows的開發,開始也不大…

視頻圖像傳輸學習筆記-基礎小知識(一)

攝像頭DVP與MIPI區別 DVP是并口,需要PCLK、VSYNC、HSYNC、D[0:11]——可以是8/10/12bit數據,看ISP或baseband是否支持;總線PCLK極限大約在96M左右,而且走線長度不能過長,所有DVP最大速率最好控制在72M以…

java程序員面試交流項目經驗

粘貼自:https://blog.csdn.net/wangyuxuan_java/article/details/8778211 1:請你介紹一下你自己 這是面試官常問的問題。一般人回答這個問題過于平常,只說姓名、愛好、工作經驗,這些簡歷上都有。其實,面試官最希望知道…

Windows7旗艦版磁盤分區詳解—附分區步驟截圖

最近工作中配置使用聯想的Thinkpad TL系列本本.當然原裝的系統時剛發布的Windows RTM旗艦版.在考慮買之前也參考了戴爾 蘋果的等等, 但個人私下也是一直在用Tinkpad系列, 相比其他的品牌本人還是比較鐘情于Tinkpad 非常實用的鍵盤. 以及簡潔的外觀.買回來一看這個TL系列原裝的系…

outlook存檔郵件_如何在Outlook 2013中存檔電子郵件

outlook存檔郵件We’ve always been told that backing up our data is a good idea. Well, that same concept can extend to email as well. You may want to archive your email every so often, such as monthly, quarterly, or even yearly. 我們一直被告知備份數據是一個…

洛谷 P1736 創意吃魚法(多維DP)

題目描述 回到家中的貓貓把三桶魚全部轉移到了她那長方形大池子中,然后開始思考:到底要以何種方法吃魚呢(貓貓就是這么可愛,吃魚也要想好吃法 ^_*)。她發現,把大池子視為01矩陣(0表示對應位置無…

計算機組裝和維護_如何構建自己的計算機,第二部分:組裝在一起

計算機組裝和維護So you’ve selected your parts, double- and triple-checked their compatibility, and waited for economy shipping to bring them all to your door. It’s time to get to the fun part: putting them all together. 因此,您已經選擇了零件&a…

Python學習-集合的常見用法

st [1,2,3,4,5] ct [2,3,4,5,76] list set(["name", list, try]) list2 set(["name", list, try, but, test]) # 兩個列表去重,利用集合st set(st) #設為集合 ct set(ct) print(st, type(st))sct0 st.union(ct) #并集 sct st | ct …

Autofac之自動裝配

從容器中的可用服務中選擇一個構造函數來創造對象,這個過程叫做自動裝配。這個過程是通過反射實現的 默認 思考這么一個問題,如果注冊類型中存在多個構造函數,那么Autofac會選擇哪一個來創建類型的實例 答案是"盡可能最多參數" class ConstructorClass {p…

對Emlog 6.0 Beta的完整代碼審計過程

Emlog 6.0 beta版本,這可能是最后一篇關于PHP語言CMS的代碼審計文章,此次將詳細記錄完整的審計過程。 文章基本上完整記錄小東的對此CMS審計過程,或許顯得繁瑣,但代碼審計的過程就是這樣,發現可能項,然后精…

SINOCES 2011

突然發現又好久沒寫過日志了 是在是太懶了… 難得休假去看了眼消費電子 感覺實在是一年不如一年 佳能、索尼不見蹤影,相機滿場沒見一家(大牌子是真沒見到) 華碩技嘉微星等主板廠商同樣失蹤… PC方面,聯想貌似是來賣電腦包鼠標的&a…

esim卡與ms卡的區別_什么是eSIM,它與SIM卡有何不同?

esim卡與ms卡的區別With the launch of the Apple Watch 3, the term “eSIM” has been thrown around a lot. And now, Google’s Pixel 2 is the first phone to use this new technology, it’s time we take a closer look at what it is, what it does, and what this me…

機器學習實戰之logistic回歸分類

利用logistic回歸進行分類的主要思想:根據現有數據對分類邊界建立回歸公式,并以此進行分類。 logistic優缺點: 優點:計算代價不高,易于理解和實現。缺點:容易欠擬合,分類精度可能不高。 .適用數…

HDU 6343.Problem L. Graph Theory Homework-數學 (2018 Multi-University Training Contest 4 1012)

6343.Problem L. Graph Theory Homework 官方題解: 一篇寫的很好的博客: HDU 6343 - Problem L. Graph Theory Homework - [(偽裝成圖論題的)簡單數學題] 代碼: 1 //1012-6343-數學2 #include<iostream>3 #include<cstdio>4 #include<cstring>5 #include<…

Android GridView LruCache

照片墻這種功能現在應該算是挺常見了&#xff0c;在很多應用中你都可以經常看到照片墻的身影。它的設計思路其實也非常簡單&#xff0c;用一個GridView控件當作“墻”&#xff0c;然后隨著GridView的滾動將一張張照片貼在“墻”上&#xff0c;這些照片可以是手機本地中存儲的&a…

如何在Android TV上自定義推薦行

When you fire up Android TV, the first thing you see is a list of movies and shows the system thinks you’ll like. It’s often full of the latest flicks or hottest news, but sometimes it could just be things relevant to your interests and the apps you have…

遞歸 段錯誤 習題

段錯誤 遞歸里面算階乘 f(10000000)沒有輸出&#xff0c;使用gdb 顯示 SIGSEGV--段錯誤編譯后產生的可執行文件里面保存著什么&#xff1f;UNIX/Linux 用 ELFDOS下用COFFWindows用PE&#xff08;COFF擴充而得&#xff09;段&#xff08;segmentation&#xff09;二進制文件內的…

你知道你常用的dos和linux命令嗎?

功能 Linux MS-DOS 進入到該目錄 cd cd 列舉文件 ls dir 創建目錄 mkdir mkdir 清除屏幕 clear cls 復制文件 cp copy 移動文件 mv move 刪除文件 rm del 查看文件 less more 文件重命名 mv ren 比較文件內容 diff fc 查看當前路徑 pwd chd…