I originally received this message by Chiristian who replied to my previous one. I send a copy to the mailing list in case it may be useful for someone else too.
---------- Forwarded message ---------- From: Christian Lück <christian.lu...@ruhr-uni-bochum.de> Date: Tue, Feb 17, 2009 at 23:50 Subject: Re: [Zope3-Users] Search multiple fields with TextIndex To: Massimiliano della Rovere <massimiliano.dellarov...@gmail.com> Cc: zope3-users@zope.org Massimiliano della Rovere wrote: > Another question is: > is there a way to automatically create TextIndices for certain (all) fields > of an interface? No, I think there's not. The event subscriber to IEventoNuovoSiteMabon is the way to go. Instead of using a field manager :) I suggest you use the api of zope.interface and zope.schema to iterate over the fields and drop some. See p.64 of Philipp's book (third edition). form zope.app.catalog.text import TextIndex def catalogo_e_indice(event): gs = event.object.getSiteManager() ... # create intid utility and catalog as you did for campo in zope.schema.getFieldNames(IScheda): if not campo in ('__name__', '__parent__', 'some_field_I_want_to_drop'): catalogo[campo] = TextIndex( interface = IScheda, field_name = campo, field_callable = False) > > On Mon, Feb 16, 2009 at 17:23, Massimiliano della Rovere < > massimiliano.dellarov...@gmail.com> wrote: > >> Probably because I am a zope newbie, I have some problems in understanding >> how queries are managed. >> >> I am reading von Weithershausen book, and I notice that the >> SearchPage.__call__ method takes the query parameter. How does zope know >> that the query (I guess it is request.query or request.form.query; I wish >> zope had an interactive debugger with inspector) paramter fromthe search >> viewlet must be passed to the __call__method? I wonder about that, too. >> parameter name matching? It is a browserpage, see zope.publisher.interfaces.browser for IBrowserPage. >> >> I have the usual interface with the autohor, subject and location fields >> (the real class has over 30 fields). >> I created a search page with a form containing a field for each attribute, >> implemented a class derived from FormBase and action attribut of the form >> tag pointing to the view that should perform the search. >> >> I am thinking how the request to the catalogo.searchResults should receive >> the parameter ttyped by the user (there could be less parameter than the >> search fields). >> If you want to use the form framework have have to decide to use a method that get's called after the input was validated as a hook to call query the catalog and a new template to show the result. You could use the add-method (or createAndAdd-method) as this hook. But I think the form-framework (formlib or z3c.form) are a not felxible enough for complex search forms. It would be nice if it was possible to query one index, invert queries, choose a conjunction, and the like. It is easy to write form interaction in zope. The input is on the request attribute. I attached viewclasses and templates from my app. Well--my catalog has has less indices than yours :) .. Feel free reuse it. There are two tar balls. One (search-form.tgz) with more abstract classes that can be used to derive search forms for a catalog. It validates the input against the schema-fields from the interface and raises a UserError on failure. It works for textindices only, now. Value indices need some more logic.. I have some plans about additional features, but that's not implemented yet.. The other (example-search.tgz) uses these classes for searching for examples... >> I implemented a few bits to try to realize what I wrote. >> We have the class preparing the catalog and indices when a site istance is >> created: >> @adapter(IEventoNuovoSitoMabon) >> def catalogo_e_indice( evento ): >> gs = evento.object.getSiteManager() >> >> intids = IntIds() >> gs['intids'] = intids >> gs.registerUtility( intids, IIntIds ) >> >> catalogo = Catalog() >> gs['catalogo'] = catalogo >> gs.registerUtility( catalogo, ICatalog ) >> That looks OK. >> campi = [ i.__name__ for i in Fields(IScheda) ] #.omit('__name__', >> '__parent__', 'titolo') ] >> Do you use a field manager? >> for i in campi: >> testuale = TextIndex( >> interface = ISearchableText, >> field_name = i, >> field_callable = False >> ) >> catalogo[i] = testuale >> >> semplice = TextIndex( >> interface = ISearchableText, >> field_name = 'getSearchableText', >> field_callable = True >> ) >> catalogo[u'semplice'] = semplice >> >> >> and the data extractor: >> class TestoSchedaPerRicerca(object): >> """Estrattore del testo per le ricerche""" >> implements(ISearchableText) >> adapts(IScheda) >> >> def __init__( self, context ): >> self.context = context >> >> def __getattr__( self, attr ): # What is this method for? Does ISearchableText subclass IScheda? >> try: >> return self.context.__dict__[attr] >> except KeyError: >> raise AttributeError( attr ) >> >> def getSearchableText( self ): >> return self.context.autore + u' : ' + self.context.soggetto >> >> But now when I add a Scheda object I get the following error: >> >> 2009-02-16T17:17:33 ERROR SiteError >> http://localhost:9673/mabon/schede/+/mabon.Scheda%3D >> >> Traceback (most recent call last): >> >> File "/usr/lib/python2.4/site-packages/zope/publisher/publish.py", line >> 133, in publish >> result = publication.callObject(request, obj) >> >> File >> "/usr/lib/python2.4/site-packages/zope/app/publication/zopepublication.py", >> line 161, in callObject >> return mapply(ob, request.getPositionalArguments(), request) >> >> File "/usr/lib/python2.4/site-packages/zope/publisher/publish.py", line >> 108, in mapply >> return debug_call(obj, args) >> >> - __traceback_info__: <security proxied >> zope.app.publisher.browser.viewmeta.ModuloAggiungiScheda instance at >> 0xa87036c> >> File "/usr/lib/python2.4/site-packages/zope/publisher/publish.py", line >> 114, in debug_call >> return obj(*args) >> >> File "/usr/lib/python2.4/site-packages/zope/formlib/form.py", line 769, in >> __call__ >> self.update() >> >> File "/usr/lib/python2.4/site-packages/zope/formlib/form.py", line 750, in >> update >> result = action.success(data) >> >> File "/usr/lib/python2.4/site-packages/zope/formlib/form.py", line 594, in >> success >> return self.success_handler(self.form, self, data) >> >> File "/usr/lib/python2.4/site-packages/zope/formlib/form.py", line 861, in >> handle_add >> self.createAndAdd(data) >> >> File "/usr/lib/python2.4/site-packages/zope/formlib/form.py", line 868, in >> createAndAdd >> return self.add(ob) >> >> File "/usr/lib/python2.4/site-packages/zope/formlib/form.py", line 877, in >> add >> ob = self.context.add(object) >> >> File >> "/usr/lib/python2.4/site-packages/zope/app/container/browser/adding.py", >> line 72, in add >> container[name] = content >> >> File "/usr/lib/python2.4/site-packages/zope/app/container/sample.py", line >> 86, in __setitem__ >> setitem(self, self.__data.__setitem__, key, object) >> >> File "/usr/lib/python2.4/site-packages/zope/app/container/contained.py", >> line 593, in setitem >> notify(event) >> >> File "/usr/lib/python2.4/site-packages/zope/event/__init__.py", line 23, >> in notify >> subscriber(event) >> >> File "/usr/lib/python2.4/site-packages/zope/component/event.py", line 26, >> in dispatch >> for ignored in zope.component.subscribers(event, None): >> >> File "/usr/lib/python2.4/site-packages/zope/component/_api.py", line 130, >> in subscribers >> return sitemanager.subscribers(objects, interface) >> >> File "/usr/lib/python2.4/site-packages/zope/component/registry.py", line >> 290, in subscribers >> return self.adapters.subscribers(objects, provided) >> >> File "/usr/lib/python2.4/site-packages/zope/interface/adapter.py", line >> 535, in subscribers >> subscription(*objects) >> >> File "/usr/lib/python2.4/site-packages/zope/component/event.py", line 33, >> in objectEventNotify >> adapters = zope.component.subscribers((event.object, event), None) >> >> File "/usr/lib/python2.4/site-packages/zope/component/_api.py", line 130, >> in subscribers >> return sitemanager.subscribers(objects, interface) >> >> File "/usr/lib/python2.4/site-packages/zope/component/registry.py", line >> 290, in subscribers >> return self.adapters.subscribers(objects, provided) >> >> File "/usr/lib/python2.4/site-packages/zope/interface/adapter.py", line >> 535, in subscribers >> subscription(*objects) >> >> File "/usr/lib/python2.4/site-packages/zope/app/intid/__init__.py", line >> 169, in addIntIdSubscriber >> notify(IntIdAddedEvent(ob, event)) >> >> File "/usr/lib/python2.4/site-packages/zope/event/__init__.py", line 23, >> in notify >> subscriber(event) >> >> File "/usr/lib/python2.4/site-packages/zope/component/event.py", line 26, >> in dispatch >> for ignored in zope.component.subscribers(event, None): >> >> File "/usr/lib/python2.4/site-packages/zope/component/_api.py", line 130, >> in subscribers >> return sitemanager.subscribers(objects, interface) >> >> File "/usr/lib/python2.4/site-packages/zope/component/registry.py", line >> 290, in subscribers >> return self.adapters.subscribers(objects, provided) >> >> File "/usr/lib/python2.4/site-packages/zope/interface/adapter.py", line >> 535, in subscribers >> subscription(*objects) >> >> File "/usr/lib/python2.4/site-packages/zope/app/catalog/catalog.py", line >> 153, in indexDocSubscriber >> cat.index_doc(id, ob) >> >> File "/usr/lib/python2.4/site-packages/zope/app/catalog/catalog.py", line >> 62, in index_doc >> index.index_doc(docid, texts) >> >> File "/usr/lib/python2.4/site-packages/zope/app/catalog/attribute.py", >> line 144, in index_doc >> return super(AttributeIndex, self).index_doc(docid, value) >> File "/usr/lib/python2.4/site-packages/zope/index/text/textindex.py", line >> 45, in index_doc >> self.index.index_doc(docid, text) >> File "/usr/lib/python2.4/site-packages/zope/index/text/okapiindex.py", >> line 225, in index_doc >> count = BaseIndex.index_doc(self, docid, text) >> File "/usr/lib/python2.4/site-packages/zope/index/text/baseindex.py", line >> 95, in index_doc >> wids = self._lexicon.sourceToWordIds(text) >> File "/usr/lib/python2.4/site-packages/zope/index/text/lexicon.py", line >> 66, in sourceToWordIds >> for t in last: >> TypeError: iteration over non-sequence >> Hmm, I don't know. Which class did you instanciate your indices form? Try zope.app.catalog.text.TextIndex Hope, that helps. Regards, Christian PS. Please cc your mail to the list! -- Se proprio dovete inserirmi in una mail in una lista con indirizzi, vi prego di mettere il mio nel campo CCN: o BCC: e non in TO: CC: oppure A: ------------ skype: masdero, icq: 473891447, yim: mas_dero, msn: mas_d...@hotmail.com ------------ Mi scriva in italiano; Write me in English; Skribu al mi Esperante! ------------ Volete farmi un regalo a natale e non sapete cosa? :D http://www.boardgamegeek.com/collection/user/masdero?sort=wishlist&sortdir=asc&columns=title|thumbnail|status|rating|bggrating|plays|comment|commands&wishlist=1&ff=1
example-search.tgz
Description: GNU Zip compressed data
search-form.tgz
Description: GNU Zip compressed data
_______________________________________________ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users