2

私のアプリケーション (PHP/MySQL/JS) には、検索機能が組み込まれています。検索基準の 1 つには、さまざまなオプションのチェックボックスが含まれています。各オプション。

つまり、オプションは A と B であり、オプション A と B の両方を検索すると、オプション A のみを含む結果 1 は 50% の関連性があり、オプション A と B の両方を含む結果 2 は 100% の関連性があります。

以前は、フォーム入力に基づいて単純な SQL クエリを実行していましたが、これはデータのように "%query%" のように単純ではないため、少し難しくなりますが、一部の結果は一部の検索クエリにとってより価値があります。そうでないものもあります。

どこから始めればいいのかまったくわかりません...関連する(はっ!)読み物を教えてくれる人はいますか?

編集:熟考した後、SQLスクリプトを使用して生データを取得し、その後に何度も何度も解析を行う必要があると考えています...

しかし、キャッシュ可能なものはありませんか?:(

4

4 に答える 4

2

多くの言語で利用できる lucence プロジェクトをご覧ください

これはphpポートです http://framework.zend.com/manual/en/zend.search.lucene.html

検索するアイテムにインデックスを付け、関連する重み付けされた検索結果を返します。たとえば、「%pattern%」スタイル検索のような名前の場合、y から x を選択する方が適切です。

于 2011-05-04T02:51:43.090 に答える
1

必要なのは、solr のような強力な検索エンジンです。これを mysql の上に実装することもできますが、他のツールですぐに使用できるように既に提供されています。

于 2011-05-04T02:52:15.870 に答える
1

ここにアイデアがあります: 比較を行い、結果を合計します。合計が高いほど、より多くの基準が一致します。

このような(ばかげた)テーブルはどうですか:

  • 名前
  • 生年月日
  • dob_month
  • dob_day

1980 年 3 月 15 日と 3 つの日付コンポーネントのほとんどを共有する人を見つけます。

SELECT (dob_year = 1980) + (dob_month = 3) + (dob_day = 15) as strength, name
from user
order by strength desc
limit 1

テーブルスキャンを行わないようにするには、適切な WHERE 句とインデックスが必要ですが...

列に重みを追加することもできます。

SELECT ((dob_year = 1980)*2)

幸運を。

于 2011-05-04T03:04:58.263 に答える
0

私のコメントに対するあなたの答えを考えると、これはあなたがそれを行う方法の例です:

最初にテーブル:

CREATE TABLE `items` (
 `id` int(11) NOT NULL,
 `name` varchar(80) NOT NULL
);
CREATE TABLE `criteria` (
 `cid` int(11) NOT NULL,
 `option` varchar(80) NOT NULL,
 `value` int(1) NOT NULL
);

次に、いくつかの項目と基準の例:

INSERT INTO items (id, name) VALUES
(1,'Name1'),
(2,'Name2'),
(3,'Name3');

INSERT INTO criteria VALUES
(1,'option1',1) ,(1,'option2',1) ,(1,'option3',0),
(2,'option1',0) ,(2,'option2',1) ,(2,'option3',1),
(3,'option1',1) ,(3,'option2',0) ,(3,'option3',1);

これにより、3 つの項目と 3 つのオプションが作成され、それらにオプションが割り当てられます。

特定の「強度」で注文できる方法が複数あります。最も単純なものは次のとおりです。

SELECT i . * , c1.value + c3.value AS strength
FROM items i
JOIN criteria c1 ON c1.cid = i.id AND c1.option = 'option1'
JOIN criteria c3 ON c3.cid = i.id AND c3.option = 'option3'
ORDER BY strength DESC 

これにより、オプション 1 またはオプション 3 を持つすべてのアイテムが表示されますが、両方のオプションを持つアイテムは「上位」にランク付けされているように見えます。

これは、2 つのオプションで検索を行う場合にうまく機能します。しかし、3 つのオプションすべてを検索するとします。すべてのアイテムが同じ強さを共有するようになったため、オプションに「重み」を割り当てることが重要です。

値を強みにすることもできますが、クエリがどこでも同じオプションに常に同じ重みを割り当てるとは限らない場合は、役に立たない可能性があります。これは、次のクエリを使用して、クエリごとに簡単に実現できます。

SELECT i.* , IF(c1.value, 2, 0) + IF(c3.value, 1, 0) AS strength
FROM items i
JOIN criteria c1 ON c1.cid = i.id AND c1.option = 'option1'
JOIN criteria c3 ON c3.cid = i.id AND c3.option = 'option3'
ORDER BY strength DESC

クエリを試して、必要なものかどうかを確認してください。

また、これは処理能力の点で最善の解決策ではないことにも注意してください。インデックスを追加し、オプション フィールドを整数にし、可能な限り結果をキャッシュすることをお勧めします。

質問や追加したいことがあればコメントを残してください。

于 2011-05-04T04:11:44.523 に答える