日本語での全文検索プログラム


app.yaml

先頭のApplication ID は、各自GAE登録時に設定した Application Identifier を設定して下さい。
最後の message.py が今回のpython プログラムです。

index.html

sagasu という項目名で検索文字を入力します。

display.html

{{ ○○ }} はpython プログラムから渡されたデータ名(○○)になります。

% for message in msbg %}
から
{% endfor %}で、python プログラムから受け渡されたデータ N件分繰り返して html の生成をしています。

message.py

2行目 #! -*- coding:utf-8 -*- は、# -*- coding:utf-8 -*- でも動きます。
(どちらが正しいか不明)

実際のデータを登録するデータ定義
class MessageBord (db.Model):
  owner = db.StringProperty(multiline=True)
  content = db.StringProperty(multiline=True)
  createDT = db.StringProperty(multiline=True)

  owner  :画面入力され保存されている登録者名
  content :画面入力され保存されている検索対象となる文字列
  createDT:登録された時点の日時(日本時間変換・編集後)


索引データを登録するデータ定義
class MessIndex (db.Model):
  seldata = db.StringProperty(multiline=True)
  site = db.StringProperty()

  seldata :N-GRAM で設定された検索キーとなる文字列
  site  :seldata に対応するデータの MessageBordに登録された際のキー

--------------------------------------------------------------------------------------------
MainProc のClass

def get(self):
  template_values = {}
  path = os.path.join(os.path.dirname(__file__), 'index.html')
  self.response.out.write(template.render(path, template_values))

  受け渡しデータなしで、画面系の出力を行う、テンプレートを使用し、index.html を起動

--------------------------------------------------------------------------------------------
class SearchProc

selstart = self.request.get('sagasu')
selend = selstart + u"\uFFFD"

  検索の際のfrom to の設定
  selstart は、入力内容そのまま
  selend は、入力内容の後に、hi-value を設定(unicode)


messageindex_query = db.GqlQuery
    ("SELECT * FROM MessIndex WHERE seldata >= :1 AND seldata < :2", selstart, selend)

  db.GqlQuery によるデータ取得
  SQL の構文とほぼ同じ
  文中の :1 :2 は、可変項目の場合、GQL文内には固定項目しか書けないので、
  その為のパラメータの意味、"SELECT … ", selstart, selend が各々、:1 :2 に該当する。
  WHERE seldata >=
selstart AND seldata < selend と同じ意味になる

  注意:SELECT 記述の際に、複合条件(今回の様に >= and <)を記載する際には、
  ORDER BY はその条件に使用した項目と同じで無ければならない。という規約があって
  訳のわからないエラーになりました。
  その為、ここでは ORDER BY の使用を止めています。

for msgidx in messageidx :
 ls.append(msgidx.site)

  ls というリストに、入力したデータ(探すべきデータのキー)を追加していく


ls = list(set(ls))

  データ取得の際に、ORDER BY を付けるつもりでしたが、使用不可だった為、PYTHONの機能で
  リスト内の並べ替えをします。(何だかこんな書き方で良いらしい:便利だ)


msgtbl = []
wk_cnt = 0
while wk_cnt < len(ls):
  anyentity = db.get(ls[wk_cnt])
  msgtbl.append(anyentity)
  wk_cnt += 1

  ここがキモ、ls に保存したデータ(上記のdb.GqlQueryで取得したキー)をキーにして
  データを取得する。
  (何故、ここでこれだけの記述で、MessageBord のデータだと判るのかは不明)
  恐らく、キー情報にどのdatastore なのかの情報も入っているのだろう。

  msgtbl.append(anyentity) で、取得したデータをmsgtbl というリストに保存
  (この msgtbl を画面系に引き継ぐデータとする為)

  データの終わりまで、繰り返し処理を実施


template_values = { 'msbd': msgtbl, 'kensaku':selstart }

  msgtbl と selstart のデータを画面に渡すために、画面系テンプレート情報に設定し、
  次のw行で、画面表示


--------------------------------------------------------------------------------------------
application = webapp.WSGIApplication([('/', MainProc),('/display', SearchProc)],debug=True)

  起動が、/ の場合(最初)は、MainProcを実施する。
  起動が、/display の場合(画面から)は、SearchProcを実施する。


--------------------------------------------------------------------------------------------
def main():
  run_wsgi_app(application)
if __name__ == "__main__":
  main()

  if __name__ == "__main__": が最初に動く箇所で、main を呼出す
  main の内容はよく判らない(笑)python の標準?