2016-05-29 1 views
2

検索入力が「what is」であるとします。これは「それが何であれ」と一致し、正確なフレーズである「何か」も一致します。さて、並べ替えで正確なフレーズを最初に作るにはどうしたらいいですか?SQLite FTSの何かの前に正確なフレーズが最初にありますか?

私は昨日からこれについて考えてきましたが、私はいろいろな解決策を考え続けていますが、それぞれには何らかの形で独自の欠陥があります。ここで

はしかし、私の失敗したアプローチです(「何か」=入力を想定):

SELECT snippet(fts), 1 as rank 
FROM fts 
WHERE body MATCH '"what is"' 
UNION ALL 
SELECT snippet(fts), 2 as rank 
FROM fts 
WHERE body MATCH 'what* NEAR/3 is*' -- 3 is arbitrary 
ORDER BY rank 
  • 問題をこの1には、2つのSELECTが はとても重複があるでしょう相互に排他的ではないということです。
  • ランク列とスニペット機能が異なるため、UNIONを使用できません(最初はSTART |何がENDですか、他にSTART |何| ENDSTART |は| ENDです)。
  • this(前の質問)MATCHはORDER BY句では機能しません(結果のテーブル/選択が元のFTSテーブルではないため)。

    SELECT snippet(fts) 
    FROM fts WHERE rowId IN 
    (
    SELECT DISTINCT rowId 
    FROM 
    ( 
    SELECT rowId, 1 as rank 
    FROM fts 
    WHERE body MATCH '"what is"' 
    UNION ALL 
    SELECT rowId, 2 as rank 
    FROM fts 
    WHERE body MATCH 'what* NEAR/3 is*' 
    ORDER BY rank 
    ) 
    ) 
    WHERE body MATCH 'what* NEAR/3 is*' 
    

    私はここでやっていることは次のとおりです:

は、ここに私の現在のソリューションです最も内側のSELECTで

  1. 、私は次のSELECTでソート
  2. をやっています私は重複を除外しています(これはまだスニペットを使用していないために機能します)
  3. 最後に、rowIdが2番目の場合にスニペットを選択しています選択します。

ここでの問題は、順序が完全になくなって、あなたが期待するように、ある:(

EDIT:。

私は(私はので、強化されたクエリ構文を使用していないアンドロイドにFTS4を使用していますAndroidが)ことをサポートしている場合、私はわからない

+0

Q:Sqliteを全文検索のバージョンを使用していますか? – paulsm4

+0

FTS4。また、私はAndroidを使用しています。 –

答えて

1

あなたはFTSテーブル自体に)すべてが処理(snippet()含むFTS行う、とだけその後最上位のクエリで結果を結合する必要があります。

SELECT docid, 
     snippet, 
     MIN(rank) AS rank 
FROM (SELECT docid, 
      snippet(fts) AS snippet, 
      1 AS rank 
     FROM fts 
     WHERE body MATCH '"what is"' 
     UNION ALL 
     SELECT docid, 
      snippet(fts), 
      2 
     FROM fts 
     WHERE body MATCH 'what* NEAR/3 is*') 
GROUP BY docid 
ORDER BY MIN(rank) /*, docid*/; 

また、より一般的なパターンで可能なすべての行を取得し、かつ、ORDER BYで、より厳密に一致するかどうかをチェック:

SELECT snippet(fts) 
FROM fts 
WHERE body MATCH 'what* NEAR/3 is*' 
ORDER BY NOT (body MATCH '"what is"'); 
+0

これはうまくいった。ありがとうございました。しかし、私は実際にはどのようにGROUP BYのdocidとMIN(ランク)が異なるスニペットを持つ重複したレコードをどのように組み合わせたのか分かりません。 –

+0

SQLite 3.7.11以降では、スニペットはMIN()と一致する行から取得されます。 –

関連する問題