Mysql 从 2 个表中的 2 列进行全面搜索
Mysql Full search from 2 columns in 2 tables
我有 2 个 table。一个是问题,一个是答案,格式如下。
question(id,text,user)
answer(id,text,question_id,user)
两个table显然有相同的行数。
当用户搜索短语或单词时,我希望它在问题文本和答案文本中搜索该单词,并且 return 最常见的匹配项。
我尝试使用 mySQL 的完整搜索,但无法在 2 个不同的 table 和 2 个列上使用它。
如果可能的话,我也不想将问题和答案合并到另一个 table。
问题table:
CREATE TABLE `questions` (
`id` int(11) NOT NULL,
`message_id` int(11) DEFAULT NULL,
`text` text NOT NULL,
`answer` int(11) DEFAULT NULL,
`status` varchar(255) NOT NULL,
`user` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
ALTER TABLE `questions`
ADD PRIMARY KEY (`id`);
ALTER TABLE `questions` ADD FULLTEXT KEY `text` (`text`);
ALTER TABLE `questions`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
答案table:
CREATE TABLE `answers` (
`id` int(11) NOT NULL,
`message_id` int(11) DEFAULT NULL,
`text` text NOT NULL,
`question` int(11) NOT NULL,
`status` varchar(255) NOT NULL,
`user` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
ALTER TABLE `answers`
ADD PRIMARY KEY (`id`);
ALTER TABLE `answers` ADD FULLTEXT KEY `text` (`text`);
ALTER TABLE `answers`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
"(select id,text, 'que' as type from question WHERE text LIKE '%keyword%')
UNION
(select id,text,'ans' as type from answer WHERE text LIKE '%keyword%')";
如果您不清楚该行是从 table 中选择的,您可以检查类型。
如果您想查询多个关键字,建议将其存储在您的应用程序代码中的某个位置(即使用 explode 函数来分隔每个关键字)。
同样在应用程序代码中,尝试动态生成 WHERE 语句(因为您无法提前知道要使用的关键字数量):
String sql_where = " ";
for(int i = 0, i<search.length, i++){
if (i=0)
sql_where += "WHERE TEXT LIKE '%"+search[i]+"%';
else
sql_where += "\n OR TEXT LIKE '%"+search[i]+"%';
}
然后您需要使用以下方法查询您的两个表:
query = "SELECT ID,TEXT,'QUE' AS TYPE FROM QUESTION "+sql_where+" UNION SELECT ID,TEXT,'ANS' AS TYPE FROM ANSWER "+sql_where+";";
请注意,为每个添加类型是为了分隔结果行的来源。如果您需要显示提取结果的位置,这将对您有所帮助。
剩下的,我就简单介绍一下大概的思路。您将需要使用之前构建的搜索数组来与您的结果集进行比较。对于每个单词,尝试在每个返回的行中查找它。在旁边,您将创建一个数组来存储常见的命中和数组索引(稍后将使用)。当您在一行中找到一个单词时,它在您的计数数组中的对应条目将递增 1。
完成后,您只需根据命中的降序对计数数组重新排序。您会注意到之前创建的索引 ID 会发生偏移,这将允许您在下一阶段使用它。
对于加载,您将在计数数组上循环,并使用在计数数组中创建的索引列从结果集中加载结果条目。
假设上面的代码是一个通用的想法,因为我不知道你使用的是哪种语言
我有 2 个 table。一个是问题,一个是答案,格式如下。
question(id,text,user)
answer(id,text,question_id,user)
两个table显然有相同的行数。
当用户搜索短语或单词时,我希望它在问题文本和答案文本中搜索该单词,并且 return 最常见的匹配项。
我尝试使用 mySQL 的完整搜索,但无法在 2 个不同的 table 和 2 个列上使用它。
如果可能的话,我也不想将问题和答案合并到另一个 table。
问题table:
CREATE TABLE `questions` (
`id` int(11) NOT NULL,
`message_id` int(11) DEFAULT NULL,
`text` text NOT NULL,
`answer` int(11) DEFAULT NULL,
`status` varchar(255) NOT NULL,
`user` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
ALTER TABLE `questions`
ADD PRIMARY KEY (`id`);
ALTER TABLE `questions` ADD FULLTEXT KEY `text` (`text`);
ALTER TABLE `questions`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
答案table:
CREATE TABLE `answers` (
`id` int(11) NOT NULL,
`message_id` int(11) DEFAULT NULL,
`text` text NOT NULL,
`question` int(11) NOT NULL,
`status` varchar(255) NOT NULL,
`user` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
ALTER TABLE `answers`
ADD PRIMARY KEY (`id`);
ALTER TABLE `answers` ADD FULLTEXT KEY `text` (`text`);
ALTER TABLE `answers`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
"(select id,text, 'que' as type from question WHERE text LIKE '%keyword%')
UNION
(select id,text,'ans' as type from answer WHERE text LIKE '%keyword%')";
如果您不清楚该行是从 table 中选择的,您可以检查类型。
如果您想查询多个关键字,建议将其存储在您的应用程序代码中的某个位置(即使用 explode 函数来分隔每个关键字)。
同样在应用程序代码中,尝试动态生成 WHERE 语句(因为您无法提前知道要使用的关键字数量):
String sql_where = " ";
for(int i = 0, i<search.length, i++){
if (i=0)
sql_where += "WHERE TEXT LIKE '%"+search[i]+"%';
else
sql_where += "\n OR TEXT LIKE '%"+search[i]+"%';
}
然后您需要使用以下方法查询您的两个表:
query = "SELECT ID,TEXT,'QUE' AS TYPE FROM QUESTION "+sql_where+" UNION SELECT ID,TEXT,'ANS' AS TYPE FROM ANSWER "+sql_where+";";
请注意,为每个添加类型是为了分隔结果行的来源。如果您需要显示提取结果的位置,这将对您有所帮助。
剩下的,我就简单介绍一下大概的思路。您将需要使用之前构建的搜索数组来与您的结果集进行比较。对于每个单词,尝试在每个返回的行中查找它。在旁边,您将创建一个数组来存储常见的命中和数组索引(稍后将使用)。当您在一行中找到一个单词时,它在您的计数数组中的对应条目将递增 1。
完成后,您只需根据命中的降序对计数数组重新排序。您会注意到之前创建的索引 ID 会发生偏移,这将允许您在下一阶段使用它。
对于加载,您将在计数数组上循环,并使用在计数数组中创建的索引列从结果集中加载结果条目。
假设上面的代码是一个通用的想法,因为我不知道你使用的是哪种语言