collective / alm.solrindex

A ZCatalog index that relays queries to solr.
BSD 3-Clause "New" or "Revised" License
4 stars 4 forks source link

SolrIndex no longer queried for indexes not explicitly listed in the catalog #2

Open claytron opened 10 years ago

claytron commented 10 years ago

You can index any field in Solr by adding it to the Solr schema. On the latest Zope, you can't query those fields because of the way Products.ZCatalog.Catalog.search was changed.

It is also impossible now to only define the solr_params and do a query directly using the Solr q parameter, useful for things like dismax.

The older way was like this (from Zope 2.10):

for i in self.indexes.keys():
    index = self.getIndex(i)
    _apply_index = getattr(index, "_apply_index", None)

Now it is more explicit (from Zope 2.13):

indexes = self.indexes.keys()
for i in plan:
    if i not in indexes:
        # We can have bogus keys or the plan can contain index names
        # that have been removed in the meantime
        continue

    index = self.getIndex(i)
    _apply_index = getattr(index, "_apply_index", None)

Workaround

There is a workaround for the moment. When you install alm.solrindex, it replaces the SearchableText index with a SolrIndex. You can use this to fake the existence of that index in your query.

Let's take this example where we want to use edismax to search across SearchableText and customfield with different weights:

searchable_text = request.get('SearchableText', None)
# Set this to an empty string to trigger _apply_index, but no extra
# `q` string is added.
query['SearchableText'] = ''
query['solr_params'] = {
    'defType': 'edismax',
    'qf': 'SearchableText^1.0 customfield^5.0',
    'q': searchable_text,
}
results = catalog(**query)

This will result in the previous behavior by way of tricking the search method to apply this query and read in the solr_params.

davisagli commented 10 years ago

I think we should fix this in ZCatalog. I also have a use case for a custom index that handles multiple fields in the query. We'll need to make the catalog plan pay attention to the index's getIndexSourceNames()