Php 使用Sphinx/MySQL是否有更好的方法同时从两个表中获取数据?
在问这个问题之前,了解我实际上在做什么是很重要的 与我正在实现的功能最好的比较是Facebook的搜索功能。开始键入时,会出现一个下拉列表,其中包含各种搜索结果。在顶部,您将找到与您的搜索匹配的朋友,然后是其他匹配的人,然后是页面、事件等 我的情况是相似的,但我只想寻找两件事。用户和文档(在下面的代码中命名为ripples) 我的这个很好用。请耐心听我讲述我的案例中此功能的逻辑:Php 使用Sphinx/MySQL是否有更好的方法同时从两个表中获取数据?,php,mysql,sphinx,Php,Mysql,Sphinx,在问这个问题之前,了解我实际上在做什么是很重要的 与我正在实现的功能最好的比较是Facebook的搜索功能。开始键入时,会出现一个下拉列表,其中包含各种搜索结果。在顶部,您将找到与您的搜索匹配的朋友,然后是其他匹配的人,然后是页面、事件等 我的情况是相似的,但我只想寻找两件事。用户和文档(在下面的代码中命名为ripples) 我的这个很好用。请耐心听我讲述我的案例中此功能的逻辑: 用户关注搜索输入 Ajax请求检索登录用户的朋友/追随者/追随者,并将其缓存到客户端(这仅在用户第一次关注搜索输入时
- 在两个单独的索引上执行两个单独的Sphinx搜索。一个用于收集用户id,另一个用于收集文档id(rippleid)
- 用户查询的结果通过检查ajax请求中发送的用户id数组来循环,以避免重复在初始高速好友/追随者检查期间已经显示的用户
- 接下来,我们查询实际数据库以获取剩余用户ID的用户数据
- 然后重复相同的过程,但这一次用于文档(涟漪)
欢迎任何评论。如果没有两个MySQL查询,你真的无法逃脱。好吧,你可以,通过jsut将它们结合成一个,结合起来。或者通过创建一个新的组合“表”(一个视图或一个物化视图),但真的不认为这是值得的。两个查询是非常好的——正如您所说,它们已被索引 通过创建新的组合索引,可以使用一个sphinx索引(以及一个搜索查询)。因为您说您的密钥不是唯一的,所以必须创建一个新的合成密钥 例如 这将为您提供一个伪键和一个属性来标识结果来自哪个表。您可以使用它来获取它来自的原始表。(做同样的事情还有很多其他方法) 这允许您运行一个查询,可以得到组合结果 。。。但我不相信这是个好主意。因为如果结果是不对称的,您可能会错过结果。假设一个表有20个匹配结果,另一个表有10个匹配结果。假设您显示前10个结果,现在由于限制,第二个表的结果很可能隐藏在第一个表的下面(extream示例,实际上,希望它们混合在一起)。两个独立的查询允许您保证从每个表中获得一些结果
。。。所以在那之后。坚持你所拥有的。很好 如果没有两个MySQL查询,你真的无法逃脱。好吧,你可以,通过jsut将它们结合成一个,结合起来。或者通过创建一个新的组合“表”(一个视图或一个物化视图),但真的不认为这是值得的。两个查询是非常好的——正如您所说,它们已被索引 通过创建新的组合索引,可以使用一个sphinx索引(以及一个搜索查询)。因为您说您的密钥不是唯一的,所以必须创建一个新的合成密钥 例如 这将为您提供一个伪键和一个属性来标识结果来自哪个表。您可以使用它来获取它来自的原始表。(做同样的事情还有很多其他方法) 这允许您运行一个查询,可以得到组合结果 。。。但我不相信这是个好主意。因为如果结果是不对称的,您可能会错过结果。假设一个表有20个匹配结果,另一个表有10个匹配结果。假设您显示前10个结果,现在由于限制,第二个表中的结果很可能被隐藏 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
));
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