[Zope-dev] Getting all objects matching a given meta_type and more

Steve Alexander steve@cat-box.net
Tue, 24 Oct 2000 22:20:06 +0100


Morten W. Petersen wrote:

> I've managed using the ZCatalog now.  However, I have a small problem:
> 
> When I instansiate a ZCatalog at the root of a tree, and search
> for all objects matching a given meta-type, all the objects in
> the entire tree are returned.
> 
> Is there a way to instruct the ZCatalog instance that it should only
> return objects from within a certin part of the tree, without instansiating
> a new ZCatalog instance in the given subtree?

Yes.

Create a keyword index in your catalog called "path_kw_for_catalog".

Create an external method called "path_kw_for_catalog" that, for an 
object, returns a list of strings that uniquely represent the physical 
path to that object, and to each of its parents by containment.

Create an external method "path_kw" that, for an object, returns a 
string that uniquely represents the physical path to that object.

Then, query your catalog using that keyword index, and the results 
path_kw for the path you want results from under.

As an example, path_kw_for_catalog might return

   ['foo_bar_baz', 'foo_bar', 'foo']

for an object at http://your.server.net/foo/bar/baz

In the same example, path_kw would return 'foo_bar' for the object at 
http://your.server.net/foo/bar


I don't know whether you can use the results of 
string.join(getPhysicalPath(), '/') as a keyword in a KeywordIndex in a 
ZCatalog. In the following methods, I'm assuming that you can't. They 
can be simplified if it turns out you can.

I'm also assuming that space characters are bad in keyword indexes. 
Again, I might be completely wrong. I guess I should check.

Anyhow, these methods should give you the general idea:

from string import join, replace

def kw_path_for_catalog(self):
     keywords=[]
     pp=self.getPhysicalPath()
     for p in range(2, len(pp)+1):
         keywords=keywords+[join(map(fix_bad_chars, pp[1:p]), '_')]
     return keywords

def kw_path(self):
     return join(map(fix_bad_chars, self.getPhysicalPath()[1:]), '_')

def fix_bad_chars(s):
     return replace(s, ' ', 'x')

--
Steve Alexander
Software Engineer
Cat-Box limited
http://www.cat-box.net