【问题标题】:Mysql nested match against not returning any resultsMysql嵌套匹配不返回任何结果
【发布时间】:2015-05-02 13:56:43
【问题描述】:

我想选择匹配的子集

SELECT * FROM (
                SELECT * FROM Movie WHERE 
                MATCH(keywords) AGAINST('$mk')
            )
            WHERE MATCH(genres) AGAINST('$mg')

$mk 可能是“动作,惊悚片” $keywords 可能是“hero,guns,forest”

这似乎不起作用,或者我可能做错了什么..

两个查询都返回值。 当我将查询与 AND 运算符相结合时,它也可以工作。

我想要实现的是根据关键字从电影中获取一组然后 从这个子集中获得一个具有匹配流派的集合..如果可能的话,这将继续使用更多的键..

或者有更好、更快、更模块化的解决方案吗? 我很难理解加入我认为他们可能是一个更好的解决方案,但我不知道..

问候

【问题讨论】:

  • 尝试为内部选择语句设置别名,如:stackoverflow.com/questions/4629979/…?
  • 当我添加别名时它返回 #1191 - 找不到与列列表匹配的 FULLTEXT 索引
  • 我猜这一次它失去了 indexex

标签: php mysql select subquery match-against


【解决方案1】:

您当前方法的索引性能将异常差。

相反,创建一个临时表、索引该表和全文。

CREATE TEMPORARY TABLE `temp_movie`    
SELECT * FROM Movie WHERE 
                MATCH(keywords) AGAINST('$mk');

ALTER TABLE `temp_movie` ADD FULLTEXT INDEX(genres);

SELECT * FROM `temp_movie`
            WHERE MATCH(genres) AGAINST('$mg')

这应该执行得更快。根据具体情况,您可能希望使用非临时表并管理缓存它们。

【讨论】:

  • #1214 - 使用的表类型不支持 FULLTEXT 索引
  • temp_movie 不是 myISAM 我猜
  • 当我添加 ENGINE=MyISAM 时它工作但这次它给出了错误
  • @kutlus 这取决于您的 MySQL 版本。您也可以使用常规表而不是临时表,但之后需要清理它。
  • @kutlus 你在 PHP 中遇到的问题是临时表只在连接存在的情况下持续存在,所以你需要在同一个连接上完成它们或者不使用 MySQL 临时表(而不是您需要自己管理表清理)
【解决方案2】:

最后我设法得到了结果,但只能在 phpMyAdmin 中看到;

示例代码如下

CREATE TEMPORARY TABLE `temp_movie` ENGINE=MyISAM
    SELECT * FROM Movie WHERE MATCH(keywords) AGAINST('$mk');
        ALTER TABLE `temp_movie` ADD FULLTEXT INDEX(genres);
CREATE TEMPORARY TABLE `temp_movie2` ENGINE=MyISAM
    SELECT * FROM `temp_movie` WHERE MATCH(genres) AGAINST('$mg');
        ALTER TABLE `temp_movie2` ADD FULLTEXT INDEX(director);
    SELECT * FROM `temp_movie2` WHERE MATCH(director) AGAINST('$md');

1- 我得到与另一个临时表匹配的关键字1 2-我从 table1 获得与另一个 temp table2 匹配的流派 3- 我从 table2 中获得匹配的董事列表

它适用于 phpMyadmin BUT 中的 SQL 查询测试

  if($result = $conn->query($simquery)){
    while($similar_movie = $result->fetch_assoc()) {
    echo $similar_movie["original_title"]."<br>";
    echo "test";
    }
} 

什么都不做.. ?!?现在我认为这是一个 PHP 问题,但谁能告诉我有什么问题..?

毕业生

【讨论】:

    【解决方案3】:

    最后我做到了.. 使用 MATCH AGAINST 选择的不同选项创建了 3 个临时表 通过 id 和分数总和联合这些临时表 从最终的临时表中选择最佳匹配项:))

    这是代码,感谢所有帮助过的人..

    $simquery = "
    create temporary table t1
    SELECT *, MATCH(keywords) AGAINST('$mk') as score from Movie ORDER BY score DESC;
    ";
    $simquery2 = "
    create temporary table t2
    SELECT *, MATCH(genres) AGAINST('$mg') as score from Movie ORDER BY score DESC;
    ";
    $simquery3 = "
    create temporary table t3
    SELECT *, MATCH(overview) AGAINST('$mo') as score from Movie ORDER BY score DESC;
    ";
    $simfinal = "
    SELECT *, sum(score) FROM 
    (
     SELECT * FROM t1
     UNION 
     SELECT * FROM t2
     UNION 
     SELECT * FROM t3
    ) as tmp
    WHERE tmdb_id != ".$id." GROUP BY id ORDER BY score DESC  LIMIT 30;
    ";
    
    $conn2->query($simquery);
    $conn2->query($simquery2);
    $conn2->query($simquery3);
    
    $result = $conn2->query($simfinal);
    

    【讨论】:

      猜你喜欢
      • 2015-10-01
      • 2018-09-17
      • 1970-01-01
      • 2019-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多