簡體   English   中英

使用Sphinx / MySQL是否有更好的方法一次從兩個表中獲取數據?

[英]Is there a better way to get data from two tables at once with Sphinx/MySQL?

在問這個問題之前,重要的是要了解我實際上在做什么。

與我正在實現的功能的最佳比較將是Facebook的搜索功能。 當您開始輸入內容時,會出現一個包含各種搜索結果的下拉列表。 在頂部,您會找到名字與您的搜索相匹配的朋友,然后是與之匹配的其他人,然后是頁面,事件等。

我的情況類似,但是我只想搜索兩件事。 用戶和文檔(在下面的代碼中命名為漣漪圖)。

我的工作很好。 在我討論此功能的邏輯時,請多多包涵:

  1. 用戶專注於搜索輸入。
  2. Ajax請求檢索已登錄用戶的朋友/關注者/關注者並將其緩存在客戶端(僅在用戶首次關注搜索輸入時才會發生)
  3. 當用戶輸入內容時,高度優化的功能會對用戶名數組執行正則表達式,並構建包含頭像等的自動完成列表。
  4. 同時,對於每次按鍵,都會向下面的腳本觸發一個ajax請求,該腳本執行以下操作

    • 在兩個單獨的索引上執行兩個單獨的Sphinx搜索。 一個收集用戶ID,另一個收集文檔ID(rippleid)
    • 通過查詢ajax請求中發送的一組用戶ID來循環用戶查詢的結果,以避免重復在最初的高速朋友/關注者檢查期間已經顯示的用戶。
    • 接下來,我們查詢實際數據庫以獲取剩余用戶ID的用戶數據
    • 然后重復相同的過程,但是這次是文件(波紋)

最后,所有返回的結果都將附加到自動完成列表中。

這是PHP函數的一個示例,該函數執行獅身人面像查找並從數據庫中獲取數據。

public function search()
                {
                                $this->disableLayout();
                                $request = new Request();
                                $params = $request->getParams(GET);

//Perform sphinx textsearch include('/usr/local/lib/php/sphinxapi.php'); $sphinx = new \SphinxClient(); $sphinx->setMatchMode(SPH_MATCH_ANY); $sphinx->SetLimits(0, 4); $mysqlconn = mysql_connect("127.0.0.1:9306") or die ("Couldn't connect to MySQL."); $users = $sphinx->Query($params['data']['q'], "users"); $ripples = $sphinx->Query($params['data']['q'], "ripples"); /* *USERS */ //Loop through users and only collect ID's that are not already present if (!empty($users["matches"])) { $ids = ""; foreach($users['matches'] as $id => $data) { if($ids > ""){ $ids .= ","; } if(!isset($params['data']['e'][$id])){ $ids .= $id; } } //If there any any remaining ID's collect the data from the database and return as JSON if(!empty($ids)){ $userdataquery = "select users.userid, users.firstname, users.lastname from tellycards_user_data users where userid IN($ids) "; $query = new Query($userdataquery); $usersoutput = $query->fetchAll(); } } /* *RIPPLES */ //Loop through ripples and collect ID's if (!empty($ripples["matches"])) { $rippleids = ""; foreach($ripples['matches'] as $id => $data) { if($rippleids > ""){ $rippleids .= ","; } $rippleids .= $id; } //If there any any remaining ID's collect the data from the database and return as JSON if(!empty($rippleids)){ $rippledataquery = "select ripples.id, ripples.name, ripples.screenshot from tellycards_ripples ripples where id IN($rippleids) "; $query = new Query($rippledataquery); $ripplesoutput = $query->fetchAll(); } } header('Content-type: text/json'); echo json_encode(array( 'users' => (!empty($usersoutput)) ? $usersoutput : null, 'ripples' => (!empty($ripplesoutput)) ? $ripplesoutput : null ));

}

您可能會問為什么我們要進行初始好友查找,而不僅僅是對所有內容都使用sphinx。 通過實現上面的方法就可以了。 用戶輸入時由於在客戶端存儲了朋友的數組而獲得了即時反饋,盡管獅身人面像的速度驚人,但由於http請求,不可避免地會有一些滯后。 在實踐中,它工作得非常好,順便說一句,它似乎也是Facebook使用的方法。

還有很多JavaScript代碼可防止不必要的查找,將返回的數據添加到緩存堆等中,以便將來的搜索不需要點擊sphinx / db等。

現在終於到了我的實際問題。

當前的服務器端功能使我非常困擾。 目前,Sphinx執行了兩次搜索,MySQL執行了兩次搜索。 如何將所有這些整理為一個獅身人面像查詢和一個MySQL查詢? 有什么辦法嗎? (請記住,文檔和用戶可能共享相同的PK ID,因為它們位於MySQL的兩個完全不同的表中,並且(當前)分布在兩個單獨的索引中)。 還是有什么辦法可以將兩個MySQL查詢組合在一起,使其比擁有兩個單獨的選擇更有效率?

或者作為替代...由於查詢的簡單性,我是否最好如上所述將它們分開? (均為索引主鍵查詢)

我想我要的是任何建議/建議。

任何評論都非常歡迎。

沒有兩個MySQL查詢真的無法擺脫。 好的,您可以通過JSUT將它們與UNION合並為一個。 或通過創建一個新的組合“表”(一個視圖或一個實體化視圖)-但實際上並不認為這樣做值得。 兩個查詢都很好-正如您所說的,它們已建立索引。

您可以使用一個獅身人面像索引(因此可以使用一個搜索查詢)-通過創建新的組合索引。 因為您說密鑰不是唯一的,所以必須創建一個新的合成密鑰。

例如...

sql_query = SELECT userid*2 AS id, 1 AS table_id, firstname AS one, lastname as two FROM tellycards_user_data \
              UNION \
            SELECT (id*2)+1 as id, 2 AS table_id, name AS one, screenshot AS two FROM tellycards_ripples
sql_attr_unit = table_id

這為您提供了一個偽造的key,以及一個用於標識結果來自哪個表的屬性。 您可以使用它來獲取它來自的原始表。 (有許多其他方式可以做相同的事情)

這使您可以運行一個查詢,可以獲得合並結果。

...但是沒有說服它是一個好主意。 因為如果結果不對稱,您可能會錯過結果。 假設一張表有20個匹配結果,另一張表有10個匹配結果。 假設您顯示的是前10個結果,現在是極限,因為第二個表的結果很可能隱藏在第一個表的下方(極端示例,實際上,希望它們混合在一起)。 兩個單獨的查詢使您可以保證從每個表中獲得一些結果。

...所以畢竟。 堅持你所得到的。 沒關系。

您可以在Sphinx中存儲和檢索有關用戶和文檔的所有數據,因此不需要MySQL。

使用Sphinx QL而不是API(更好,更輕松地完成工作-> http://sphinxsearch.com/docs/current.html#sphinxql-reference

注意:不要忘記將所有要從中檢索數據的文本字段設置為sphinx.conf源中的sql_field_string

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM