18

全文検索を使用して、データベース内の2つのテーブルから複数の列を検索する必要があります。問題の2つのテーブルには、関連する列の全文索引があります。

全文検索を選択した理由:1。アクセントのある単語を簡単に検索できるようにするため(カフェ)2。単語の近接度などに応じてランク付けできるようにするため。3。「XXXのことですか?」機能性

課題を説明するために、ダミーのテーブル構造を次に示します。

テーブルブック
BookID
名前(全文索引)
メモ(全文索引)

テーブル棚
ShelfID
BookID

テーブルShelfAuthor
AuthorID
ShelfID

テーブル作成者
AuthorID
名前(全文索引)

書籍名、書籍ノート、著者名を検索する必要があります。

私はこれを達成するための2つの方法を知っています:

  1. フルテキストインデックス付きビューの使用:これは私の好みの方法でしたが、ビューをフルテキストインデックスにするには、スキーマにバインドする必要があり、外部結合がなく、一意のインデックスがあるため、これを行うことはできません。 。データを取得するために必要なビューは、これらの制約を満たしていません(データを取得するために必要な他の多くの結合テーブルが含まれています)。

  2. ストアドプロシージャでの結合の使用:このアプローチの問題は、結果をランクで並べ替える必要があることです。テーブル全体で複数の結合を行っている場合、SQLServerはデフォルトで複数のフィールドを検索しません。2つのリンクされたテーブルで2つの個別のCONTAINSクエリを組み合わせることができますが、2つの検索クエリから組み合わせたランクを抽出する方法がわかりません。たとえば、「Arthur」を検索する場合、BookクエリとAuthorクエリの両方の結果を考慮し、それに応じて重み付けする必要があります。

4

6 に答える 6

14

FREETEXTTABLE を使用すると、結合されたテーブルの結果ごとにマージされたランクを計算するアルゴリズムを設計するだけで済みます。以下の例では、結果を book テーブルからのヒットに偏らせています。

SELECT b.Name, a.Name, bkt.[Rank] + akt.[Rank]/2 AS [Rank]
FROM Book b
INNER JOIN Author a ON b.AuthorID = a.AuthorID
INNER JOIN FREETEXTTABLE(Book, Name, @criteria) bkt ON b.ContentID = bkt.[Key] 
LEFT JOIN FREETEXTTABLE(Author, Name, @criteria) akt ON a.AuthorID = akt.[Key]
ORDER BY [Rank] DESC

この例では、スキーマを単純化したことに注意してください。

于 2008-12-31T18:24:27.777 に答える
6

私はあなたと同じ問題を抱えていましたが、実際には10個のテーブルが関係していました(Usersテーブルと他のいくつかの情報)

各テーブルの WHERE 句で FREETEXT を使用して最初のクエリを実行しましたが、クエリに時間がかかりすぎました。

次に、代わりに FREETEXTTABLE を使用し、各テーブルのキー列で null 以外の値をチェックすることについていくつかの返信を見ましたが、実行にも時間がかかりました。

FREETEXTTABLE と UNION の組み合わせを使用して修正しました。

SELECT Users.* FROM Users INNER JOIN
(SELECT Users.UserId FROM Users INNER JOIN FREETEXTTABLE(Users, (column1, column2), @variableWithSearchTerm) UsersFT ON Users.UserId = UsersFT.key
UNION
SELECT Table1.UserId FROM Table1 INNER JOIN FREETEXTTABLE(Table1, TextColumn, @variableWithSearchTerm) Table1FT ON Table1.UserId = Table1FT.key
UNION
SELECT Table2.UserId FROM Table2 INNER JOIN FREETEXTTABLE(Table2, TextColumn, @variableWithSearchTerm) Table2FT ON Table2.UserId = Table2FT.key
... --same for all tables
) fts ON Users.UserId = fts.UserId

これにより、信じられないほど高速であることが証明されました。

お役に立てば幸いです。

于 2016-08-08T16:05:09.347 に答える
3

FWIW、同様の状況で、DBA は専用の全文検索テーブルを維持するために DML トリガーを作成しました。多くの制限があるため、マテリアライズド ビューを使用することはできませんでした。

于 2011-02-19T18:04:17.210 に答える
1

ストアドプロシージャを使用します。全文メソッドまたは並べ替え可能なランクを返すもの。それらが互いにどのように重み付けされるかはわかりませんが、しばらくの間いじくり回してそれを理解できると確信しています. 例えば:

Select SearchResults.key, SearchResults.rank From FREETEXTTABLE(myColumn, *, @searchString) as SearchResults Order By SearchResults.rank Desc
于 2008-12-31T18:15:22.240 に答える
0

この回答はかなり遅れていますが、プライマリ テーブルを変更できない場合にこれを行う 1 つの方法は、検索パラメーターを 1 つの列に追加して新しいテーブルを作成することです。

次に、その列に全文索引を作成し、その列にクエリを実行します。

SELECT 
    FT_TBL.[EANHotelID]                 AS HotelID, 
    ISNULL(FT_TBL.[Name],'-')           AS HotelName,
    ISNULL(FT_TBL.[Address1],'-')       AS HotelAddress,
    ISNULL(FT_TBL.[City],'-')           AS HotelCity,
    ISNULL(FT_TBL.[StateProvince],'-')  AS HotelCountyState,
    ISNULL(FT_TBL.[PostalCode],'-')     AS HotelPostZipCode,
    ISNULL(FT_TBL.[Latitude],0.00)      AS HotelLatitude,
    ISNULL(FT_TBL.[Longitude],0.00)     AS HotelLongitude,
    ISNULL(FT_TBL.[CheckInTime],'-')    AS HotelCheckinTime,
    ISNULL(FT_TBL.[CheckOutTime],'-')   AS HotelCheckOutTime,
    ISNULL(b.[CountryName],'-')         AS HotelCountry,
    ISNULL(c.PropertyDescription,'-')   AS HotelDescription,
    KEY_TBL.RANK 

    FROM [EAN].[dbo].[tblactivepropertylist] AS FT_TBL INNER JOIN
     CONTAINSTABLE ([EAN].[dbo].[tblEanFullTextSearch], FullTextSearchColumn, @s)
      AS KEY_TBL
    ON FT_TBL.EANHotelID = KEY_TBL.[KEY]
    INNER JOIN [EAN].[dbo].[tblCountrylist] b
    ON FT_TBL.Country = b.CountryCode
    INNER JOIN [EAN].[dbo].[tblPropertyDescriptionList] c
    ON FT_TBL.[EANHotelID] = c.EANHotelID

上記の [EAN].[dbo].[tblEanFullTextSearch] のコードでは、FullTextSearchColumn はフィールドが追加された新しいテーブルと列です。データを表示するテーブルへの結合を使用して、新しいテーブルでクエリを実行できるようになりました。 .

お役に立てれば

于 2016-12-30T23:51:51.203 に答える