国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

Elasticsearch——利用Parent-Child關(guān)系解決大數(shù)據(jù)場(chǎng)景下的實(shí)時(shí)查詢(xún)

2019-11-09 13:28:14
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

表與表之間的關(guān)聯(lián)基本上是所有業(yè)務(wù)系統(tǒng)都存在的,RDBMS通過(guò)外鍵實(shí)現(xiàn),MongoDB通過(guò)嵌入式子文檔解決,那么Elasticsearch怎么解決這個(gè)問(wèn)題呢?答案就是Parent-Child關(guān)聯(lián)(參考文檔)

業(yè)務(wù)場(chǎng)景

有一個(gè)廣告的分發(fā)系統(tǒng),為了更精準(zhǔn)的做廣告的推送,除了自身積累的數(shù)據(jù)以外,還會(huì)從其他合作方通過(guò)數(shù)據(jù)交換(當(dāng)然這些都是脫敏的數(shù)據(jù))的方式獲取更多用戶(hù)行為數(shù)據(jù),例如從音樂(lè)網(wǎng)站獲取聽(tīng)的音樂(lè)列表、從購(gòu)物網(wǎng)站獲取最近的購(gòu)物類(lèi)別、從書(shū)評(píng)網(wǎng)站獲取最近瀏覽的圖書(shū)等等。這些來(lái)自于外部的數(shù)據(jù),有以下幾個(gè)問(wèn)題:

并不是每個(gè)用戶(hù)都有全部的數(shù)據(jù),比如有些用戶(hù)只有書(shū)評(píng)和音樂(lè)信息,而有些用戶(hù)沒(méi)有任何外部信息某一類(lèi)外部的數(shù)據(jù)源可能包含幾個(gè)網(wǎng)站,比如音樂(lè)網(wǎng)站有A、B、C三個(gè)網(wǎng)站,它們提供的數(shù)據(jù)格式也并不一致

在進(jìn)行廣告推送時(shí),需要實(shí)時(shí)查詢(xún)一個(gè)用戶(hù)的信息完成精準(zhǔn)推薦。比如實(shí)時(shí)查詢(xún)滿(mǎn)足下面條件的用戶(hù):

最近一個(gè)月,經(jīng)常在早上、傍晚或者晚上連續(xù)一個(gè)小時(shí)的音樂(lè);購(gòu)買(mǎi)過(guò)跑鞋、運(yùn)動(dòng)手表等跑步裝備且購(gòu)買(mǎi)過(guò)或點(diǎn)評(píng)過(guò)運(yùn)動(dòng)類(lèi)書(shū)籍

再繼續(xù)下面的(十分簡(jiǎn)化)解決方案之前,可以先思考下

解決方案

這是典型應(yīng)用大數(shù)據(jù)進(jìn)行個(gè)性化精準(zhǔn)推薦的應(yīng)用場(chǎng)景,在省卻了數(shù)據(jù)清洗、評(píng)分等各種步驟以后,簡(jiǎn)化為一個(gè)查詢(xún)問(wèn)題。分析可以發(fā)現(xiàn)數(shù)據(jù)問(wèn)題的核心就是:無(wú)固定表結(jié)構(gòu),是典型的Schema-Free的NoSQL應(yīng)用場(chǎng)景,第一個(gè)反應(yīng)出來(lái)的就是MongoDB。

MongoDB

MongoDB用作以上的數(shù)據(jù)存儲(chǔ),毫無(wú)疑問(wèn)具有天然的優(yōu)勢(shì),可以將每個(gè)來(lái)源的數(shù)據(jù)都作為user的一個(gè)子文檔存儲(chǔ),查詢(xún)時(shí)也只是在這一個(gè)Collection上進(jìn)行(可能有人會(huì)說(shuō)這種方案太蠢了,的確是,不過(guò)也要看產(chǎn)品所處的階段)。當(dāng)然這樣做的問(wèn)題也顯而易見(jiàn): 為了查詢(xún)速度,索引是必須要?jiǎng)?chuàng)建的。可是因?yàn)閿?shù)據(jù)源不斷變化,那么索引的維護(hù)就會(huì)變成一個(gè)災(zāi)難。一旦忘記創(chuàng)建查詢(xún),可能就會(huì)拖死整個(gè)系統(tǒng)。

下面當(dāng)然就是主角上場(chǎng)了。

Elasticsearch

定調(diào): 1. 由于字段是變化,因此必須使用動(dòng)態(tài)Mapping(文檔) 2. 由于Parent-Child的關(guān)系需要?jiǎng)?chuàng)建索引(Create Index)時(shí)就確定,因此必須使用固定的Mapping(文檔)

我又檢查了上面兩條,的確是沒(méi)有說(shuō)錯(cuò)。

其實(shí)很簡(jiǎn)單,在創(chuàng)建索引時(shí),只需指定父子關(guān)系,無(wú)需指定其他未知字段。因?yàn)橐A(yù)先指定type的父子關(guān)系,所以就必須先確定type。這是用兩個(gè)type:user和user_action,那么創(chuàng)建索引時(shí)的Mapping大致如下:

{ "mappings": { "user": {}, "user_action": { "_parent" : { "type": "user" } } }}

我好像把文檔中的例子抄了一遍,不多實(shí)際情況的確是這樣。

那么在添加文檔到索引中時(shí),對(duì)于user就需要指定id,而user_action需要指定parent,例如:

es = Elasticsearch()_id = 27_user = { 'id': 27, 'name': 'Tigger Fei'}# 索引用戶(hù)文檔es.index(index='user_index', doc_type='user', id=str(_id), body=_user)# 索引用戶(hù)行為文檔, type字段表示列表# 音樂(lè)_music = { 'type': 'music', 'user': 27, 'period': 'morning', 'duration': 78, 'category': 'running', 'time': '2017-01-29 12:30:00'}es.index(index='user_index', doc_type='user_action', parent=str(_id), body=_music)# 圖書(shū),_book = { 'type': 'book,' 'user': 27, 'name': '我的第一個(gè)馬拉松', 'category': 'running', 'time': '2017-01-30 12:30:00'}es.index(index='user_index', doc_type='user_action', parent=str(_id), body=_book)

如何完成上面的查詢(xún)呢,如下:

POST user_index/user/_search{ "query": { "bool": { "filter": [ { "has_child": { "type": "user_action", "query": { "bool": { "filter": [ {"term": {"type": "music"}}, {"range": {"duration": {"gte": 60}}}, {"range": { "time": { "gte": "2017-01-07 00:00:00", "format": "yyyy-MM-dd HH:mm:ss" } }}, {"term": {"category": "running"}}, {"terms": {"period": ["morning", "night"]}} ] } } } }, { "has_child": { "type": "user_action", "query": { "bool": { "filter": [ {"range": { "time": { "gte": "2017-01-07 00:00:00", "format": "yyyy-MM-dd HH:mm:ss" } }}, {"term": {"type": "book"}}, {"term": {"category": "running"}} ] } } } } ] } }}

好了,這個(gè)簡(jiǎn)單的解決方案就完了。


發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 德清县| 枣强县| 江永县| 海门市| 旺苍县| 德安县| 陵川县| 泾川县| 绍兴县| 石景山区| 同仁县| 东源县| 佳木斯市| 蓝山县| 清镇市| 泾源县| 大名县| 合阳县| 兴义市| 卢氏县| 大田县| 顺平县| 永靖县| 淮北市| 且末县| 海口市| 江山市| 景德镇市| 杭锦后旗| 沈丘县| 瓮安县| 徐州市| 同江市| 济宁市| 耒阳市| 开封市| 景东| 榆树市| 孝感市| 兴安盟| 尼勒克县|