MySQL 搜索查询 - 也从标签搜索:(

发布于 2024-09-06 15:25:56 字数 1838 浏览 1 评论 0原文

因此,我有一个允许用户提交代码的网络应用程序。提交内容存储在 code 表中,其中的几列是全文索引的。到目前为止,这就是我执行搜索的方式。

但是,用户可以使用任意数量的标签来提交提交的内容 - 我希望这些也包含在搜索中(但是,全部都在一个查询中......)。标签存储在表 tags 中,并且有一个名为 code_tags 的交集表,用于存储 code_idtag_id >。标准的东西。

我的“旧”搜索查询是这样的:

SELECT *
  FROM code
 WHERE MATCH (title, summary, code) AGAINST ('$searchterm')

$searchterm 是通过 PHP $_POST 获取的。

所以我尝试编写更多的“高级”查询:

SELECT code.*, 
       code_tags.*, 
       tags.*, 
       tags.tag
  FROM code, code_tags, tags
 WHERE code_tags.code_id = code.id
   AND tags.id = code_tags.tag_id
   AND MATCH (title, summary, code) AGAINST ('$searchterm') 

但是这一切所做的只是返回...什么都没有。即使输入了完全有效的搜索词。

所以我注释掉了最后一行:

SELECT code.*, code_tags.*, tags.*, tags.tag
  FROM code, code_tags, tags
 WHERE code_tags.code_id = code.id
   AND tags.id = code_tags.tag_id
-- AND MATCH (title, summary, code) AGAINST ('php') 

这将返回数据库中的每个提交。但是,同一行的重复次数与它的标签数相同(唯一的区别是每个返回行中的标签)。

例如:

查询失败

所以,最后,我想我会很聪明,并对标签进行 GROUP_CONCAT:

SELECT code.*, code_tags.*, tags.*, GROUP_CONCAT(tags.tag SEPARATOR ' ') AS taggroup
  FROM code, code_tags, tags
 WHERE code_tags.code_id = code.id
   AND tags.id = code_tags.tag_id
-- AND MATCH (title, summary, code, taggroup) AGAINST ('php')`

这有两个相当大的问题。

  1. 将最后一个 AND MATCH 行注释掉后,仅返回一行(包含 code 表中第一个条目的所有详细信息 - 并且 taggroup 列出了每个标签,对于每个 !
  2. 包含最后一个 AND MATCH 行后,我收到以下错误:'where 子句'中的未知列'taggroup' - 该死!

提交 :S

So, I've got a webapp that lets users submit code. The submissions are stored in the code table, and a couple of columns of that are Fulltext-Indexed. This is how I have been performing searches up until now.

But, users can submit their submissions with as many tags as they like - and I'd like these to be included in the search too (but, all in one query...). The tags are stored in the table tags, and there's an intersection table called code_tags that stores the code_id and the tag_id. Standard stuff.

My 'old' search query was this:

SELECT *
  FROM code
 WHERE MATCH (title, summary, code) AGAINST ('$searchterm')

$searchterm was fetched via PHP $_POST.

So I tried to write a bit more of an 'advanced' query:

SELECT code.*, 
       code_tags.*, 
       tags.*, 
       tags.tag
  FROM code, code_tags, tags
 WHERE code_tags.code_id = code.id
   AND tags.id = code_tags.tag_id
   AND MATCH (title, summary, code) AGAINST ('$searchterm') 

But all this did was return... nothing. Even when a perfectly valid search term was entered.

So I commented out the last line:

SELECT code.*, code_tags.*, tags.*, tags.tag
  FROM code, code_tags, tags
 WHERE code_tags.code_id = code.id
   AND tags.id = code_tags.tag_id
-- AND MATCH (title, summary, code) AGAINST ('php') 

This returns every submission in the database. But, the same row is repeated as many times as there are tags for it (the only difference being, the tag in each returned row).

E.G:

Query Fail

So, finally, I thought I'd be clever and GROUP_CONCAT the tags:

SELECT code.*, code_tags.*, tags.*, GROUP_CONCAT(tags.tag SEPARATOR ' ') AS taggroup
  FROM code, code_tags, tags
 WHERE code_tags.code_id = code.id
   AND tags.id = code_tags.tag_id
-- AND MATCH (title, summary, code, taggroup) AGAINST ('php')`

There are two pretty big problems with this.

  1. With the last AND MATCH line commented out, only one row is returned (with all the details of the first entry in the code table - and taggroup lists every tag, for every submission!
  2. With the last AND MATCH line included, I get the following error: Unknown column 'taggroup' in 'where clause' - damn!

So, what am I meant to do? :S

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深爱成瘾 2024-09-13 15:25:56

原因如下:

SELECT code.*, code_tags.*, tags.*, tags.tag
  FROM code, code_tags, tags
 WHERE code_tags.code_id = code.id
   AND tags.id = code_tags.tag_id
   AND MATCH (title, summary, code) AGAINST ('php') 

...不返回任何结果是因为您没有任何 code 表记录,其标题/摘要/代码匹配“php”并且与 >CODE_TAGSTAGS 表。切换到 ANSI-92 JOIN 语法,尝试:

SELECT c.*, ct.*
  FROM CODE c
  JOIN CODE_TAGS ct ON ct.code_id = c.id
 WHERE MATCH (title, summary, code) AGAINST ('php')

如果没有返回任何内容,那么您的问题是满足全文搜索的记录都与 CODE_TAGS 表中的任何内容都不相关 - 您需要先添加关联才能工作。如果将 JOIN 添加到 TAGS 表会影响任何内容,那么应该会有所启发:

SELECT c.*, ct.*
  FROM CODE c
  JOIN CODE_TAGS ct ON ct.code_id = c.id
  JOIN TAGS t ON t.id = ct.tag_id
 WHERE MATCH (title, summary, code) AGAINST ('php')

The reason the following:

SELECT code.*, code_tags.*, tags.*, tags.tag
  FROM code, code_tags, tags
 WHERE code_tags.code_id = code.id
   AND tags.id = code_tags.tag_id
   AND MATCH (title, summary, code) AGAINST ('php') 

...doesn't return any results is that you don't have any code table records whose title/summary/code match "php" AND have relations to either the CODE_TAGS or TAGS tables. Switching to ANSI-92 JOIN syntax, try:

SELECT c.*, ct.*
  FROM CODE c
  JOIN CODE_TAGS ct ON ct.code_id = c.id
 WHERE MATCH (title, summary, code) AGAINST ('php')

If nothing is returned, then you're problem is that none of the records that satisfy the Full Text Search are related to anything in the CODE_TAGS table -- you'll need to add associations before it will work. That should shine some light on if adding the JOIN to the TAGS table will affect anything:

SELECT c.*, ct.*
  FROM CODE c
  JOIN CODE_TAGS ct ON ct.code_id = c.id
  JOIN TAGS t ON t.id = ct.tag_id
 WHERE MATCH (title, summary, code) AGAINST ('php')
缘字诀 2024-09-13 15:25:56

不知道如何同时选择 tags.*GROUP_CONCAT 但自从我现在使用 MySQL 以来已经有一段时间了,无论如何,将您的数据加入并按你想要的列应该可以工作。下面的例子。

SELECT code.id, code.title, GROUP_CONCAT(tags.tag SEPARATOR ' ')
  FROM code
 INNER JOIN code_tags ON code.id = code_tags.code_id
 INNER JOIN tags ON code_tags.tag_id = tags.id
 WHERE MATCH (code.title, code.summary, code.code) AGAINST ('php')
 GROUP BY code.id, code.title

Not sure how you can select tags.* and GROUP_CONCAT at the same time but been a while since I was working with MySQL now, anyway join your data in and group by the columns you want should work. Example below.

SELECT code.id, code.title, GROUP_CONCAT(tags.tag SEPARATOR ' ')
  FROM code
 INNER JOIN code_tags ON code.id = code_tags.code_id
 INNER JOIN tags ON code_tags.tag_id = tags.id
 WHERE MATCH (code.title, code.summary, code.code) AGAINST ('php')
 GROUP BY code.id, code.title
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文