4

インデックスキーの値が欠落しているオブジェクトのzopeカタログを検索したいと思います。出来ますか?

たとえば、後続のコード行について考えてみます。

from Products.CMFCore.utils import getToolByName
catalog = getToolByName(context, 'portal_catalog')
results = catalog.searchResults({'portal_type': 'Event', 'review_state': 'pending'})

portal_typeやreview_stateではなく特定のアイテムが挿入されていないオブジェクトに興味がある場合はどうすればよいですか?

4

2 に答える 2

7

両方のタイプを検索できますが、MissingValueエントリを検索するには、内部カタログ データ構造のカスタム処理が必要です。

インデックスはオブジェクトから値を取得し、それにインデックスを付けます。が存在する場合AttributeError、インデックスはそのオブジェクトの何も格納しません。同じフィールドが返された列の一部である場合、MissingValueそのフィールドのインデックスが空であることを示すために a が与えられます。

次の例ではcatalog、サイトの portal_catalog ツールを指す変数があると想定しています。たとえば、getToolByName(context, 'portal_catalog')または類似の結果。

なしを探しています

多くのインデックスで None をうまく検索できます。

catalog(myKeywordIndex=None)

問題は、ほとんどのインデックス タイプが値として無視Noneされることです。したがって、Date および Path インデックスでの検索Noneは失敗します。インデックスの None とブール インデックスを無視します。インデックス作成時に None を False にします。

シーケンスの一部でない限り、キーワード インデックスNoneも同様に無視されます。インデックス化されたメソッドが返された場合、[None]喜んでインデックス化されますがNone、それ自体ではインデックス化されません。

フィールド インデックスはインデックスに格納Noneされます。

各インデックスは一意の値を表示できるNoneため、次を呼び出して、特定のインデックスに値が保存されているかどうかを確認できます。

catalog.uniqueValuesFor(indexname)

欠損値の検索

これは少しトリッキーです。各インデックスは、インデックスを作成したオブジェクトを追跡します。たとえば、オブジェクトが削除されたときにインデックスからデータを削除できるようにします。同時に、カタログは全体として索引付けしたオブジェクトを追跡します。

したがって、これら 2 つの情報のセットの違いを計算できます。これは、公開された API を呼び出すときに常にカタログが行うことですが、このトリックでは、そのような公開 API はありません。カタログの内部にアクセスして、これらのセットを取得する必要があります。

幸いなことに、これらはすべて BTree セットであるため、操作は比較的効率的です。これが私がそれを行う方法です:

from BTrees.IIBTree import IISet, difference

def missing_entries_for_index(catalog, index_name):
    # Return the difference between catalog and index ids
    index = catalog._catalog.getIndex(index_name)
    referenced = IISet(index.referencedObjects()) # Works with any UnIndex-based index
    return (
        difference(IISet(catalog._catalog.paths), referenced),
        len(catalog) - len(referenced)
    )

このmissing_entries_for_indexメソッドは、カタログ ID の IISet とその長さを返します。each は、名前付きインデックスにエントリがないカタログ レコードへのポインタです。次に、 を使用catalog.getpathしてそれをオブジェクトへのフル パスに変換したり、 を使用catalog.getMetadataForRIDしてメタデータ値の辞書を取得したり、 を使用catalog.getobjectして元のオブジェクト自体を取得したり、 を使用catalog._catalog[]してカタログ ブレーンを取得したりできます。

次のメソッドは、通常のカタログ検索から取得するのと同じように、カタログ結果セットを提供します。

from ZCatalog.Lazy import LazyMap

def not_indexed_results(catalog, index_name):
    rs, length = missing_entries_for_index(catalog, index_name)
    return LazyMap(catalog._catalog.__getitem__, rs.keys(), length)
于 2012-06-27T10:24:16.813 に答える
0

よろしくお願いします。あなたが提案するリンクを実際に読んで、私はそれがトリックなしでは不可能であることを発見します。私はpypiから報告します:

インデックスのネガティブフィルタリングは、アイテムをインデックスに値を持つアイテムに制限することに注意してください。したがって、10個のドキュメントで、そのうち5個が値1のfooインデックスにある場合、1以外のクエリは、値のない5個のアイテムの代わりにアイテムを返しません。特定のインデックスのすべてのアイテムを検討する場合は、ダミー/デフォルト値にインデックスを付ける必要があります。

したがって、アイテムにデフォルト値を指定して探す必要があります。

于 2012-06-27T07:34:06.577 に答える