[Zope] Zcatalog question

Casey Duncan casey at zope.com
Tue Jan 6 14:02:10 EST 2004


On Tue, 6 Jan 2004 08:55:50 -0700
Steve Lenti <slenti at abqpubco.com> wrote:

> I have a Zcatalog setup to handle bunches of small xml files that are
> being stored as DTML Documents.  When I do a query I would like to
> make the results unique on a fieldindex that is called ad_num.  Is
> there a way to filter the results of a query to be unique on a
> fieldindex.  I realize I can step through the results and filter out
> the duplicates but is there a more optimal way of doing this.  I tried
> messing with something like this:
> 
> context.Catalog({ 'adTextidx' : adTextidx}).uniqueValuesFor('ad_num')
> 
> but this unfortunatly does not work.

uniqueValuesFor can only be called on the catalog (not a result set) and
returns all unique keys for that index.

Are you looking for all of the unique values that occur in the index
only for the objects in the result set? In that case, you could do
something like this in an external method:

(Rather than stepping through the result records, this steps through the
rids, which should be quite a lot faster)::

  from BTrees.OOBTree import OOTreeSet

  def uniqueValuesInResult(self, query, index):
      catalog = self._catalog
      search_idx = catalog.getIndex('adTextidx')
      rs = search_idx._apply_index(query)
      if rs is not None:
          rs = rs[0] # Get set of rids
          # Get all the values from the index for these rids
          uniq_idx = catalog.getIndex(index)
          values = [uniq_idx.getEntryForObject(rid) 
                    for rid in rs.keys()]
          # Construct a set to find the unique values
          return OOTreeSet(values).keys() 
      else:
          # No results
          return []

Note that this assumes you are searching a single index. The low-level
Catalog API does not expose rids in many cases, so this external method
talks to the index directly.

You would call this in the context of a ZCatalog like so:

  context.Catalog.uniqueValuesInResult({'adTextidx':adTextidx},
'ad_num')

This is untested code, so if it blows up, let me know and I'll try to
fix it. If it works it might be worth posting on ZopeLabs.

hth,

-Casey



More information about the Zope mailing list