[Zope] ZCatalog question. boolean and wildcards.

Dieter Maurer dieter@handshake.de
Sat, 14 Oct 2000 12:18:05 +0200 (CEST)


Hannes Grund writes:
 > When mixing boolean operators and wildcards '*' in queries within a Textindex
 > the 'AND' operator is replaced by 'OR'. 
 > Also, the possibility of constructing nested terms using brackets seems 
 > to be not supported (contrary to the chapter 'Searching and indexing' from the Zope book).
 > The setting is straightforward, several indexes (text-index, keyword-indexes)
 > are used indexing a about 5000 Zclasses.
 > Are there any patches to apply or what else can i do ?
Sorry, the patch I posted yesterday was not complete.

There have been too more problems:

  * if the wildcard expansion could not find matching words,
    my patch created an empty subquery.
    Such queries, unfortunately, can not be handled by
    "UnTextIndex.evaluate".

    The new patch, instead creates a new search term,
    'no_expansion_for_<pattern>'. Hopefully, this term is not
    indexed and thus gives the same results as
    the empty subquery.

    Of cause, this is a hack.
    The ZCatalog maintainer should find a better solution.

  * The ZCatalog, more precisely, "UnTextIndex.__getitem__"
    still raises an "IndexError" exception, when one searches
    for a term that is not indexed.
    The result is "no data matches your query", even for
    an "or" query.

    I had already put a patch for this error in the collector
    for Zope 2.2.1, but apparently, DC decided not to
    look at it.


Please discard my patch from yesterday.
You may give the new patch (appended) a try.


Dieter

--- lib/python/SearchIndex/:GlobbingLexicon.py	Mon Aug 28 19:30:06 2000
+++ lib/python/SearchIndex/GlobbingLexicon.py	Sat Oct 14 11:54:24 2000
@@ -230,10 +230,22 @@
             if ( (self.multi_wc in w) or
                 (self.single_wc in w) ):
                 wids = self.get(w)
-                for wid in wids:
-                    if words:
-                        words.append(Or)
-                    words.append(self._inverseLex[wid])
+                #for wid in wids:
+                #    if words:
+                #        words.append(Or)
+                #    words.append(self._inverseLex[wid])
+		if wids:
+		    words.append(map(self._inverseLex.get,wids))
+		else:
+		    words.append('no_expansion_for_' + w)
+		    # We do this here, as "UnTextIndex.evaluate"
+		    #    can not handle empty subqueries
+		    # We use as expansion some expression that
+		    #    is likely not in the catalog but
+		    #    gives some indication to the problem
+		    #    in case "ResultList" does something
+		    #    with its "src" argument.
+		    #    This is a hack, though!
             else:
                 words.append(w)
 
--- lib/python/SearchIndex/:UnTextIndex.py	Fri Oct 13 23:29:00 2000
+++ lib/python/SearchIndex/UnTextIndex.py	Sat Oct 14 11:57:38 2000
@@ -347,8 +347,10 @@
         if len(src) == 1:
             src=src[0]
             if src[:1]=='"' and src[-1:]=='"': return self[src]
-            r = self._index.get(self.getLexicon(self._lexicon).get(src)[0],
-                                None)
+	    codes= self.getLexicon(self._lexicon).get(src)
+	    if codes:
+                r = self._index.get(codes[0], None)
+	    else: r= None # maybe do something, if len(codes) > 1
             if r is None: r = {}
             return ResultList(r, (src,), self)
             
@@ -490,11 +492,11 @@
         except IndexError: raise QueryError, "Malformed query"
 
         t=type(left)
-        if t is ListType: left = evaluate(left, self)
+        if t is ListType: left = self.evaluate(left)
         elif t is StringType: left=self[left]
 
         t=type(right)
-        if t is ListType: right = evaluate(right, self)
+        if t is ListType: right = self.evaluate(right)
         elif t is StringType: right=self[right]
 
         return (left, right)