我試圖通過避免包含相同單詞的多個記錄來限制我的數據庫的大小,因此我已經構建了兩個表,用於將關鍵字與其他行表。mySQL加入三個表並搜索一個表中找到的幾個關鍵字
作爲一個例子,我們使用follwing搜索輸入:「找到我」
什麼願望去得到一個打擊,是的product_id = 106 難道我只是在產品名稱搜索PRODUCT_NAME?不可以,因爲產品可以與其他關鍵字關聯,而這些關鍵字不屬於product_name的一部分。
表:ec_products
product_id | product_name | is_deleted
---------------------------------------------
106 | some product | 0
表:ec_keywords_index
word_id | keyword
---------------------------------------------
55 | find
61 | my
77 | product
表:ec_keyword_relations
word_id | application_id | related_id
------------------------------------------------
55 | 1 | 106
61 | 1 | 106
77 | 1 | 106
所以,我現在想,當我輸入 「找我」 到我的搜索輸入是:
- 我只想要命中其中ec_keyword_relations.application_id = 1
- 我的搜索字符串中的所有單詞都應該與產品相關。例如。如果我將搜索輸入更改爲「找到我的褲子」,我們不應該找到product_id = 106.
這是我到目前爲止嘗試過的(並且我知道我離工作解決方案很遠暫且):
$searchInput = 'find my';
$keywords = explode(' ', $searchInput);
$keyword_count = count($keywords);
$n = 1;
$query = '';
foreach($keywords as $keyword) {
if ($n !== $keyword_count) {
$query_ext = ' AND ';
} else {
$query_ext = '';
}
$query .= "(ec_keywords_index.keyword LIKE '%$keyword%')" . $query_ext;
++$n;
}
$query = "
SELECT
ec_products.product_name
FROM
ec_products
LEFT JOIN ec_search_word_relations
ON ec_keyword_relations.related_id = ec_products.product_id
LEFT JOIN ec_keywords_index
ON ec_keywords_index.word_id = ec_keyword_relations.word_id
WHERE
($query)
AND
ec_products.is_deleted = '0'
AND
ec_keyword_relations.application_id = '1'
GROUP BY
ec_products.product_id
ORDER BY
ec_products.product_name ASC
LIMIT
100";
$stmt = $mysqli->prepare($query);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($name);
while ($stmt->fetch()) {
echo $name;
}
UPDATE:
經過一番擺弄周圍,我想出了這個解決方案預期這只是工作。 (就性能而言)它是一個好的還是壞的解決方案?
$searchInput = 'find my';
$keywords = explode(' ', $searchInput);
$keyword_count = count($keywords);
$n = 1;
$where_query = '';
$having_query = '';
foreach($keywords as $keyword) {
if ($n != $keyword_count) {
$w_query_ext = ' OR ';
$h_query_ext = ' AND ';
} else {
$w_query_ext = '';
$h_query_ext = '';
}
$where_query .= "ec_keywords_index.keyword LIKE '%" . $keyword . "%'" . $w_query_ext;
$having_query .= "related_keywords LIKE '%" . $keyword . "%'" . $h_query_ext;
++$n;
}
$query = "
SELECT
ec_products.product_name,
GROUP_CONCAT(' ', ec_keywords_index.keyword) AS 'related_keywords'
FROM
ec_products,
ec_keywords_index
LEFT JOIN
ec_keyword_relations
ON ec_keyword_relations.word_id = ec_keywords_index.word_id
WHERE ($where_query)
AND ec_products.product_id = ec_keyword_relations.related_id
AND ec_keyword_relations.application_id = '1'
AND ec_products.is_deleted = '0'
GROUP BY
ec_products.product_name
HAVING
($having_query)
LIMIT
100";
$stmt = $mysqli->prepare($query);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($name);
while ($stmt->fetch()) {
echo $name;
}
上面的例子輸出這樣的查詢:
SELECT
ec_products.product_name,
GROUP_CONCAT(' ', ec_keywords_index.keyword) AS 'related_keywords'
FROM
ec_products,
ec_keywords_index
LEFT JOIN
ec_keyword_relations
ON ec_keyword_relations.word_id = ec_keywords_index.word_id
WHERE (ec_keywords_index.keyword LIKE '%find%' OR ec_keywords_index.keyword LIKE '%my%')
AND ec_products.product_id = ec_keyword_relations.related_id
AND ec_keyword_relations.application_id = '1'
AND ec_products.is_deleted = '0'
GROUP BY
ec_products.product_name
HAVING
(related_keywords LIKE '%find%' AND related_keywords LIKE '%my%')
LIMIT
100
我使用GROUP_CONCAT創建一個包含所有與產品相關的關鍵字一欄,然後我的WHERE子句僅用來選擇在我的搜索字符串中實際找到的關鍵字...然後使用HAVING子句在使用GROUP_CONCAT的列構建中進行搜索。以實例