0

App Engineの公式テキスト検索機能がリリースされるまで使用できる、簡単で効果的なAppEngineのテキスト検索を実装したいと考えていました。そこにはライブラリがあるようですが、何か新しいものをインストールするのはいつも面倒です。これが有効な戦略かどうか疑問に思います。

1)テキスト検索可能である必要がある各プロパティをテキストフラグメントのセット(リスト)に分割します2)これらのリストを追加してレコードを保存します3)検索するときは、リストプロパティで等式フィルターを使用します

たとえば、レコードがある場合:

{
  firstName="Jon";
  lastName="Doe";
}

私はこのようなプロパティを保存することができます:

{
  firstName="Jon";
  lastName="Doe";

  // not case sensative:
  firstNameSearchable=["j","o", "n","jo","on","jon"];   
  lastNameSerachable=["D","o","e","do","oe","doe"];
}

次に、検索するために、これを実行して、上記のレコードが返されることを期待できます。

//pseudo-code:
SELECT person 
WHERE firstNameSearchable=="jo" AND
      lastNameSearchable=="oe"

これはテキスト検索の実装方法ですか?特に段落などがある場合、インデックスが制御不能になるのをどのように防ぎますか?通常使用される他の圧縮戦略はありますか?単純なものが必要な場合は、これでうまくいくかもしれませんが、発生する可能性のある問題を知っておくと便利です。

アップデート:::

さて、この概念はおそらく正当であることがわかりました。このブログ投稿も参照しています:http://googleappengine.blogspot.com/2010/04/making-your-app-searchable-using-self.html

注:上記のブログ投稿のソースコードは、現在のバージョンのLuceneでは機能しません。グーグルはとにかくすぐにアプリエンジンの独自のテキスト検索を出すことになっているので、私は古いバージョン(2.9.3)をクイックフィックスとしてインストールしました。

以下の応答で提案されている解決策は簡単な修正ですが、大きなテーブルの制限により、クエリの1つのプロパティでのみ非等式演算子を使用できるため、1つのフィールドでクエリを実行している場合にのみ機能します。

db.GqlQuery("SELECT * FROM MyModel WHERE prop >= :1 AND prop < :2", "abc", u"abc" + u"\ufffd")

複数のプロパティについてクエリを実行する場合は、プロパティごとにインデックスを保存できます。私の場合、これを小さなテキストフィールドの自動提案機能に使用しており、実際にはドキュメント内の単語やフレーズの一致を検索していません(これには上記のブログ投稿の実装を使用できます)。これは非常に単純で、ライブラリは必要ありません。また、誰かが「Larry」を検索している場合、「arry」という単語の途中から始めるのではなく、「La...」と入力することから始めると思います。したがって、プロパティが人の名前などの場合、インデックスには最初の文字で始まる部分文字列しか含まれないため、「Larry」のインデックスは{"l"、 "la"、 "lar"、 "larr "、"ラリー "}

電話番号のように、最初または中桁から検索したいデータに対して、別のことをしました。この場合、長さ3の文字列で始まるサブ文字列のセット全体を保存したので、電話番号 "123-456-7890"は{"123"、 "234"、 "345"、...になります。 。"123456789"、 "234567890"、 "1234567890"}、合計(10 *((10 + 1)/ 2))-(10 + 9)=41インデックス...実際に私がしたことはもう少しでした使用される可能性が低いいくつかのサブストリングを削除するために複雑ですが、あなたはその考えを理解します。

次に、クエリは次のようになります。(Pseaudo Code)SELECT * from Person WHERE firstNameSearchIndex == "lar" phonenumberSearchIndex == "1234"

App Engineが機能する方法は、クエリのサブ文字列がプロパティ内のいずれかのサブ文字列と一致する場合、それが一致としてカウントされることです。

4

1 に答える 1

2

実際には、これは拡張できません。n文字の文字列の場合、n個の階乗インデックスエントリが必要です。500文字の文字列は、すべての可能なサブ文字列をキャプチャするために1.2 * 10^1134インデックスを必要とします。エンティティがデータストアへの書き込みを完了する前に、あなたは老齢で亡くなります。

search.SearchableModelのような実装は、単語ごとに1つのインデックスエントリを作成します。これはもう少し現実的です。任意の部分文字列を検索することはできませんが、プレフィックスを一致させるためのトリックがあります。

ドキュメントから:

db.GqlQuery( "SELECT * FROM MyModel WHERE prop> =:1 AND prop <:2"、 "abc"、u "abc" + u "\ ufffd")

これは、すべてのMyModelエンティティを、文字abcで始まる文字列プロパティpropと一致させます。ユニコード文字列u"\ufffd"は、可能な最大のUnicode文字を表します。プロパティ値がインデックスでソートされている場合、この範囲に含まれる値は、指定されたプレフィックスで始まるすべての値です。

于 2010-10-11T17:32:23.817 に答える