ドキュメントの取得、削除、インデックス再作成(更新)

2012 年 10 月、Amy Unruh
Google Developer Relations

はじめに

このレッスンでは、ドキュメント ID を使用してドキュメントを取得する方法、インデックスからドキュメントを削除する方法、既存のドキュメントのインデックスを再作成して更新する方法について説明します。ここで示す便利なメソッドについては、サンプル アプリケーションの docs.py ファイルですべて確認できます。

目標

Search API を使用してドキュメントを取得、削除、インデックス再作成する方法について学習します。

要件

このクラスに先行するクラス: Python Search API スタートガイド

次の内容も必要になります。

ドキュメント ID でドキュメントを取得する

クエリを使用するのではなく、ドキュメント ID でドキュメントを取得しなければならないことがあります。サンプル アプリケーションの場合は、商品レビューの作成に関連して必要になります。新しいレビューによって Datastore に関連した記帳が行われ、関連する製品ドキュメントが新しい平均評価で更新されます。

Index.get メソッドを使用してドキュメントを取得し、ドキュメント ID を doc_id パラメータとして指定できます。

@classmethod
def getDoc(cls, doc_id):
  """Return the document with the given doc id."""
  index = cls.getIndex()
  return index.get(doc_id=doc_id)

インデックスからドキュメントを削除する

インデックスからドキュメントを削除するには、そのドキュメント ID をインデックスの delete メソッドに渡します。また、DeleteError の例外についても把握しておく必要があります。

@classmethod
def deleteDocById(cls, doc_id):
  """Delete the doc with the given doc id."""
  try:
    cls.getIndex().delete(doc_id)
  except search.DeleteError:
    logging.exception("Error removing doc id %s.", doc_id)

インデックスの get_range メソッドを使用すると、特定のインデックスからすべてのドキュメントを削除できます。効率を上げるには、ids_only パラメータを True に設定します。そうすることで、返されたドキュメント オブジェクトには ID のみが含まれ、不要なドキュメント フィールドが含まれなくなります。返された ID に基づいて、各ドキュメントを削除します。

@classmethod
def deleteAllInIndex(cls):
  """Delete all the docs in the given index."""
  docindex = cls.getIndex()

  try:
    while True:
      # until no more documents, get a list of documents,
      # constraining the returned objects to contain only the doc ids,
      # extract the doc ids, and delete the docs.
      document_ids = [document.doc_id for document in docindex.get_range(ids_only=True)]
      if not document_ids:
        break
      docindex.delete(document_ids)
  except search.DeleteError:
    logging.exception("Error removing documents:")

このメソッドは、インデックスにドキュメントがなくなるまでループします。これは、get_range が同時に返すドキュメントは 1000 のみであり(デフォルトの上限は 100)、インデックス全体をクリアするには、複数の呼び出しが必要になる場合があるためです。

インデックスの削除

完全にインデックスを削除するには、インデックス内のすべてのドキュメントを削除してからインデックス スキーマを削除します。

ドキュメントのインデックスを再作成する

インデックス付きドキュメントの更新または変更を行うには、同じドキュメント ID を使用して新しいドキュメント オブジェクトをインデックスに追加するだけです。すでにインデックスに同じ ID を持つドキュメントが含まれている場合、既存のドキュメントが更新され、インデックスが再作成されます。インデックスに同じ ID を持つドキュメントが存在しない場合には、新しいドキュメントが指定された ID で追加されます。

サンプル アプリケーションでは、サンプル商品データのプロダクト ID をドキュメント ID として使用します(コードを見れば、Datastore の Product エンティティ ID としてプロダクト ID も使用されているのが確認できます)。ドキュメント ID はプロダクト ID と同じであるため、変更された商品データのインデックスを簡単に再作成できます。データソースからプロダクト ID を取得するため、インデックス付きドキュメントの更新の際に、プロダクト ID を先に取得する必要がありません。

では、この処理について確認していきましょう。最初に、サンプル アプリケーションの data/sample_data_books.csvdata/sample_data_books_update.csv をみてください。これらには、アプリケーションのサンプル商品データが含まれています。ユーザーが「すべてのデータストアを削除して、商品データのインデックスを作成し、サンプル商品データを読み込む」のリンクをクリックすると、data/sample_data_books.csv 内のすべてのデータがインポートされ、既存のインデックス コンテンツが削除されます。この処理に関連してここで説明したいのは、新しいドキュメントが作成されると、その ID がプロダクト ID に設定されるということです。

d = search.Document(doc_id=product_id, fields=docfields)

プロダクトのインデックスにドキュメントが追加されます。

次に、ユーザーが「商品更新データの読み込みのデモ」をクリックすると、data/sample_data_books_update.csv 内のデータがインデックスに追加されます。このファイルのエントリの一部は、プロダクト ID が既存のドキュメントに対応していることから、既存のブック ドキュメントを更新します。ファイルのその他のエントリでは、既存のドキュメントにプロダクト ID がないことから、新しいブックを定義します。

プロダクト ID をドキュメント ID として使用しているので、上記のようにドキュメント ID をプロダクト ID に設定して新しいドキュメントを作成し、各ドキュメントに追加するだけで可能です。プロダクト ID を持つドキュメントが他にないか把握しておく必要はありません。同じプロダクト ID を持つドキュメントが存在する場合、新しいコンテンツで更新され、インデックスが再作成されます。存在しない場合は、新しいドキュメントのインデックスが作成されます。

サンプルのアプリケーション コードを見ると、他にも想定される状況のあることがわかります。たとえば、既存のドキュメントの情報を保持する必要があったり、更新したドキュメントに情報を設定する必要があったりする場合です。そのようなときには、既存のドキュメントがあれば、アクセスする必要があります。

まとめと確認

このレッスンでは、ドキュメント ID でドキュメントを取得する方法と、ドキュメント ID を削除および更新する方法について説明しました。

Python Search API の詳細に関するクラスが終了したことになります。このクラスのコースと先行のクラスで、Search API を使用するアプリケーションを構築するための基本的なツールキットに習熟しました。自身で簡単なアプリケーションを作成したり、サンプル アプリケーションをさらに修正してみたりしてください。

Stack Overflow については、google-app-engine タグを使用するか、App Engine グループでお問い合わせください。

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...