Apache Solr Views and a terrible way to handle results per content type in Drupal 7

Posted July 18, 2013 by adp6j

I’m betting on there being a better way to do this. There just has to be. But I haven’t figured it out, so here is how we’re using (abusing?) Views PHP and ApacheSolr Views to deliver results on a per-content type basis.

apachesolr views with per content type results

To start with we create a new view

choose the correct solr index

After the new view is created load a bunch of fields on in – it may be useful to remember that “Bundle” will return a content type by name, the “content” will return all of the fielded content in an string, and “entity_id” has the node value. One cool thing you can do with the node id is then pass that as an argument to another view using Views Field View - be aware that this is somewhat performance naughty, but it’ll work if you want access to images in your results and don’t feel like creating a custom module to index images.

exclude fields from display

After getting your fields loaded I set their values to “Exclude from display” in the field settings

Our view with a few fields loaded

And of course don’t forget to add a Global: PHP field – here’s our view now

And really… I’m pretty embarrassed by this. It’s raunchy and rank. It works. The facets facet and so on… I just can’t believe that this is the way to do things. I’ve looked at Solr Panels and feel like there must be a way to do better – maybe having multiple views pre-faceted by bundle at the view level and the made in to content panes? Anyone with some sense of how to improve this is encouraged to chime in…. Bueller? Bueller….

how does search api vary with regards to handling displays per content type? or is this something done with panels. I’ve looked at the search api and don’t see where it differs? Thanks for the comment though – am more than glad to check it out.

I am unclear what you are trying to accomplish with respect to “displays per content type”. Can you let me know?

In any case, SearchAPI etc. are not responsible for displaying results. That is the work, of course, of some combination of: each content type’s display manager (perhaps augmented by Display Suite and/or Panelizer displays); Views; and Panels (including Mini Panels).

For what it is worth, my site’s search is architected as follows:

1. Each content type has a DS (Display Suite) view mode called “Search result”. Each “Search result” display contains a single field, which is a content-type specific embedded view of type-specific data for a single node.

2. Each of these embedded single-node views employs time-based caching, for example 6 hours for the result cache and the display/rendering cache. Each single-node view can of course contain whatever data you want and lay it out however you want with whatever display plugin you want.

3. The search view returns multiple rows, each of which boils down to the search-indexed node that matches the search view’s exposed and unexposed filters; the most common exposed filter is a match-all-keywords (or a match the exact phrase) text filter.

4. Each of the search view’s rows displays the respective node’s Full Content, rendered by that node’s “Search result” view mode. Thus each rendered row is cached, whereas you absolutely do not want to cache the search view itself.

5. The search view is based on the specific SearchAPI Solr index you want to employ. That index is connected to a Solr server. The index specifies the fields to index, one of which can be each node’s fully rendered HTML content; you will also normally index the title plus any important taxonomy terms, etc.

6. The search index is further configured, via its Workflow tab, to index only selected content types, to ignore a set of “stop words”, and so on.

7. The search index also configures the desired search facets, based on Facet API of course.

8. FacetAPI supplies a block for each configured facet. These blocks augment the search view’s exposed filter(s). I use Page Manager/Panels to host the search view’s results in the main region of the page. Another region of the page holds both the search view’s exposed filter(s) and its configured facets. (These can be presented in another page region as tabs.)

9. If you are also supporting SearchAPI Saved Searches, then the Saved Search blocks can be added to the filters-and-facets region of the page, or to another page region.

10. You can of course utilize content-type-specific search views, each of which is based on your master SearchAPI Solr index. In this case, a search view uses a non-exposed filter that narrows its content types to one or several of the indexed types.

You could overwrite the view template and use a preprocess hook to alter the variables passed to the template.

You could also use a module like “display suite”. With this module, you can manage your displays for each content type. I always prefer working with “node displays” instead of “fields” inside views. You get the advantage that the node is rendered so all node features are also added (example: you get contextual links). But because you are working with solr. I guess when you use this approach, only the id of the node will be used from solr and the node display will be rendered with a database query.

Hi Bruno,
my feeling is that if I have to overwrite the view template and write a preprocess hook I’m not that much better off. I think you’re spot on with the display suite option as we’re already using that in our node displays… am going to test that + the Search API Bob recommended to see whether those will play nice together. Thanks!