両方のタイプを検索できますが、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)