0

自分が取り組んでいるサイトの簡単な検索を作成したいと思います。データベースに特定のカテゴリIDを保持し、オプションで複数のタグにリンクできるアイテムがあります。

入ってくる検索用語をすべて取得し、category.nameフィールドとtag.nameフィールドにクエリを実行して、それらの用語に一致するアイテムを見つけたいと思います。

これを実行し、最も近い(最も一致する)アイテムごとに結果を並べ替える効率的で迅速なクエリを作成する方法についてのアドバイスを探しています

関連するテーブルのクイックバージョンは次のとおりです。

アイテム

id | カテゴリ| タイトル| 説明

カテゴリー

id | 名前| parentId

鬼ごっこ

id | 名前| 使用

item_tag

itemId | tagId

4

2 に答える 2

1

私はまだあなたが何を望んでいるのか完全には理解していませんでした。
さて、これが私たちが議論する最初のバージョンです。
次のようにビューを作成することをお勧めします。

CREATE OR REPLACE VIEW `search_view` AS
SELECT
  i.id    AS `item_id`,
  i.title AS `item_title`,
  c.id    AS `cat_id`,
  c.name  AS `cat_name`,
  t.id    AS `tag_id`,
  t.name  AS `tag_name`
FROM item AS i
LEFT OUTER JOIN item_tag AS it
  ON (i.id = it.itemId)
LEFT OUTER JOIN tag AS t
  ON (it.tagId = t.id)
LEFT OUTER JOIN category AS c
  ON (i.category = c.id)
WHERE ((t.id IS NOT NULL) OR (c.id IS NOT NULL));

次に、近くの何かを使用してビューからクエリを実行します

SELECT
  *,
  (
    IF(tag_name like ?, 2, 0)
    + IF(cat_name like ?, 4, 0)
    + IF(item_title like ?, 1, 0)
  ) AS `priority`
  FROM search_view
GROUP BY item_id
ORDER BY SUM(priority);

上記のコードにはテストはありません。問題があれば報告してください

【初版】 PHPを使っていますね。さて、PHP文字列関数を使用してクエリを正規化することができます; 1つの方法は、出現するすべての'、'を'|'に置き換え、余分なスペースを削除して、次のクエリを実行することです。[@VARを使用した例を示します(実際には、入力文字列に置き換えます)]

SET @VAR = 'notebook|samsung';
SELECT
  *,
  (
    IF (tag_name REGEXP CONCAT('.*(', @VAR, ').*'), 2, 0)
    + IF (cat_name REGEXP CONCAT('.*(', @VAR, ').*'), 4, 0)
    + IF (item_title REGEXP CONCAT('.*(', @VAR, ').*'), 1, 0)
  ) AS `priority`
  FROM search_view
ORDER BY priority DESC;

今回はテストしました。はい、MySQL関数を使用できますREPLACE(REPLACE(@VAR,' ',''), ',', '|')。ただし、PHP(またはJava、Pythonなど)で実行することをお勧めします。

于 2013-03-23T06:05:34.443 に答える
0
SELECT item.*
FROM items
LEFT JOIN categories
       ON categories.name = '< input name >'
      AND categories.id = items.category
LEFT JOIN item_tags
      AND item_tags.itemId = items.id
LEFT JOIN tags
       ON tags.name = '< input name >'
      AND tags.id = item_tags.tagId
WHERE categories.id IS NOT NULL
   OR tags.id IS NOT NULL
ORDER BY COUNT(items.id) DESC;

これは最速の方法ではないかもしれません。基本的に、カテゴリとタグの名前が正しいことを確認しながら、カテゴリとタグをアイテムに結合したままにします。where句のcategoryまたはitem_tagに一致しないすべてのアイテムを除外します。

もう1つの方法は、一時テーブルを作成することです。正しい名前のすべてのカテゴリに1つ、正しい名前のすべてのタグに1つ作成します。次に、items WHERE items.idINcategories_tableまたはitems.idINtags_tableを選択できます。

于 2013-03-23T02:56:25.627 に答える