Reputation: 3220
I am using Products.AdvancedQuery to build a replacement LiveSearch mechanism for my site. So far everything works perfectly, but the standard query performs a search on all available content-types, including the ones marked as non-searchable in the @@search-controlpanel.
I'd like AdvancedQuery to filter out the non-searchable ones dynamically, according to what is specified in @@search-controlpanel. How can I do this?
If AQ cannot do it, I can filter the results right after querying the catalog. I'd need a list of content-type names (or interfaces) that are marked as searchable. How can I obtain such a list?
Upvotes: 1
Views: 425
Reputation: 3220
Ok, thanks to sdupton's suggestion I found a way to make it work.
This is the solution (obvious imports omitted):
from Products.AdvancedQuery import (Eq, Not, In,
RankByQueries_Sum, MatchGlob)
from my.product.interfaces import IQuery
class CatalogQuery(object):
implements(IQuery)
...
def _search(self, q, limit):
"""Perform the Catalog search on the 'SearchableText' index
using phrase 'q', and filter any content types
blacklisted as 'unsearchable' in the '@@search-controlpanel'.
"""
# ask the portal_properties tool for a list of names of
# unsearchable content types
ptool = getToolByName(self.context, 'portal_properties')
types_not_searched = ptool.site_properties.types_not_searched
# define the search ranking strategy
rs = RankByQueries_Sum(
(Eq('Title', q), 16),
(Eq('Description', q), 8)
)
# tune the normalizer
norm = 1 + rs.getQueryValueSum()
# prepare the search glob
glob = "".join((q, "*"))
# build the query statement, filter using unsearchable list
query = MatchGlob('SearchableText', glob) & Not(
In('portal_type', types_not_searched)
)
# perform the search using the portal catalog tool
brains = self._ctool.evalAdvancedQuery(query, (rs,))
return brains[:limit], norm
Upvotes: 2
Reputation: 1869
Assuming you can obtain a tuple or list of the types that the control panel blacklists programmatically, this might be as simple as (imports elided):
>>> query = myquery & AdvancedQuery.Not(AdvancedQuery.In(MY_TYPE_BLACKLIST_HERE))
>>> result = getToolByName(context, 'portal_catalog').evalAdvancedQuery(query)
Upvotes: 2