我想实现类似mysql search title, description and multi rows tag的搜索.
这是我的表格:
书籍:
+----+-----------------------+-------------+
| id | name | description |
+----+-----------------------+-------------+
| 1 | Me Before You | [TEXT] |
| 2 | How To Win Friends... | [TEXT] |
| 3 | The Girl on the Train | [TEXT] |
| 4 | After You | [TEXT] |
| 5 | We Were Liars | [TEXT] |
+----+-----------------------+-------------+
标签:
+----+-----------------------+
| id | tag |
+----+-----------------------+
| 1 | romance |
| 2 | thriller |
| 3 | fantasy |
| 4 | science fiction |
| 5 | drama |
| 6 | friends |
+----+-----------------------+
Books_tags:
+---------+--------+
| book_id | tag_id |
+---------+--------+
| 1 | 1 |
| 1 | 3 |
| 2 | 3 |
| 3 | 3 |
| 3 | 5 |
| 4 | 1 |
| 4 | 5 |
| 4 | 6 |
| 5 | 2 |
| 5 | 6 |
+---------+--------+
以下是一些示例搜索和所需的结果:
'romance' -> books 1, 4
'friends' -> books 2, 4, 5
'friends win' -> books 2
'fantasy' -> books 2, 3
'fantasy train' -> books 3
在构建 SQL 查询之前,一个函数会检查每个给定的关键字,如果它是一次标记。例如,在这种情况下,我的问题是:
- 案例:3/
- 关键词: friend 赢/
- 标签: friend
查询:
SELECT SQL_CALC_FOUND_ROWS
b.id, b.name,
MATCH(b.name) AGAINST('*friends* *win*' IN BOOLEAN MODE) as name_score,
MATCH(t.tag) AGAINST('friends' IN BOOLEAN MODE)as tag_score
FROM
books b
LEFT JOIN
books_tags bt ON bt.book_id = b.id
LEFT JOIN
tags t ON t.id = bt.tag_id
WHERE
MATCH(b.name) AGAINST('*friends win*' IN BOOLEAN MODE)
OR MATCH(t.tag) AGAINST('friends' IN BOOLEAN MODE)
GROUP BY
b.id
ORDER BY
name_score DESC, (tag_score + name_score) DESC
结果:
array (size=3)
0 => string '2' (length=1)
1 => string '4' (length=1)
2 => string '5' (length=1)
在这种情况下,关键字“friends”已经与标题匹配,因此必须减少条件并且不应再搜索标签。我该如何解决?
最佳答案
这就是你想要的吗?...
数据集
DROP TABLE IF EXISTS books;
CREATE TABLE books
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,name VARCHAR(50) NOT NULL
,FULLTEXT(name)
) ENGINE = MyISAM;
INSERT INTO books VALUES
(1,'Me Before You'),
(2,'How To Win Friends...'),
(3,'The Girl on the Train'),
(4,'After You'),
(5,'We Were Liars');
DROP TABLE IF EXISTS tags;
CREATE TABLE tags
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,tag VARCHAR(20) NOT NULL
);
INSERT INTO tags VALUES
(1,'romance'),
(2,'thriller'),
(3,'fantasy'),
(4,'science fiction'),
(5,'drama'),
(6,'friends');
DROP TABLE IF EXISTS books_tags;
CREATE TABLE books_tags
(book_id INT NOT NULL
,tag_id INT NOT NULL
,PRIMARY KEY(book_id,tag_id)
);
INSERT INTO books_tags VALUES
(1,1),
(1,3),
(2,3),
(3,3),
(3,5),
(4,1),
(4,5),
(4,6),
(5,2),
(5,6);
查询和结果
SELECT DISTINCT b.*
, MATCH(b.name) AGAINST('*friends* *win*' IN BOOLEAN MODE) name_score
FROM books b
LEFT
JOIN books_tags bt
ON bt.book_id = b.id
LEFT
JOIN tags t
ON t.id = bt.tag_id
AND t.tag IN ('friends','win')
WHERE t.id IS NULL;
+----+-----------------------+------------+
| id | name | name_score |
+----+-----------------------+------------+
| 1 | Me Before You | 0 |
| 2 | How To Win Friends... | 1 |
| 3 | The Girl on the Train | 0 |
| 4 | After You | 0 |
| 5 | We Were Liars | 0 |
+----+-----------------------+------------+
关于php - mysql搜索标题、描述和多行标签(关于条件),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38180116/