您可以搜索这两种类型,但搜索MissingValue
条目需要自定义处理内部目录数据结构。
索引从对象中获取值,并为其编制索引。如果有AttributeError
或类似的,索引不存储该对象的任何内容,并且如果相同的字段是返回列的一部分,在这种情况下,MissingValue
将给出 a 以指示该字段的索引为空。
在以下示例中,我假设您有一个catalog
指向站点的 portal_catalog 工具的变量;例如getToolByName(context, 'portal_catalog')
或类似的结果。
搜索无
您可以在许多索引中搜索None 就好了:
catalog(myKeywordIndex=None)
问题是大多数索引类型都忽略None
了一个值。因此,搜索None
将在日期和路径索引上失败;他们忽略索引上的 None 和布尔索引;他们在索引时将 None 变为 False。
关键字索引None
也会忽略,除非它是序列的一部分。如果索引方法返回[None]
,它会很高兴被索引,但None
它自己不会。
字段索引确实存储None
在索引中。
请注意,每个索引都可以显示唯一值,因此您可以None
通过调用来检查给定索引是否存储了值:
catalog.uniqueValuesFor(indexname)
搜索缺失值
这有点棘手。例如,每个索引都会跟踪它已索引的对象,以便能够在删除对象时从索引中删除数据。同时,目录会跟踪它作为一个整体索引的对象。
因此,我们可以计算这两组信息之间的差异。当您调用已发布的 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)