It would be nice to allow pure faceted browsing, with no search keys, and allow the browsing to be started from any page (not just the search page).

From what I understand, the following changes would be needed to achieve this:

1) Allow searching with empty keys: As mentioned here, we could override the search form's validation to allow empty keys. With empty keys, hook_search() would not build any search query.

2) Allow facet blocks to be displayed on any page: Instead of returning when apachesolr_has_searched() is false, hook_block() would build its own query (a slightly simpler one, with no 'q' param, no boosts, nor any other params useless to facets) and perform a search. This would be made easier after moving the query building logic into usable function(s) (perhaps through #436792: Modular handling of params). And when apachesolr_has_searched() is true, hook_block() would simply continue doing the same thing as it currently does (use the available search response).

Later on, we could figure out #348218: Search within current set to make the search flow usable.

CommentFileSizeAuthor
#10 facets-anywhere-442976.patch1.25 KBdavid lesieur

Comments

pwolanin’s picture

Well, the search blocks should still, I think, be disabled by default on all except the search page.

We'd either a per-block config setting or something else to handle this.

janusman’s picture

I'd like to hear your opinion on this idea:

Are these "facet blocks", when the facets are taxonomy terms, duplicating the functionality of modules like tagadelic? Why/why not?

david lesieur’s picture

I don't think this would be duplicating functionality. While Tagadelic (or other modules) could launch a search (if we alter the term paths), it cannot refine an existing search (AFAIK, there is no easy way to have it take the current search results into account to filter its tags). A facet block, on the other hand, could either start or refine a search. Using the same block for both purposes ensures that we provide users with a consistent interface for both actions.

Also, facet blocks are not just for taxonomies, but anything that's "facetable". Facet blocks are based on Solr data rather than Drupal data.
When used with taxonomies, the facet blocks could even reflect term hierarchies (per #401234: Reflect hierarchical taxonomy vocabulary in facet) whereas Tagadelic only shows flat lists of terms.

Scott Reynolds’s picture

O man facet navigation is really exciting. Those facet blocks can then be tied to a search form block thereby allowing quiet a bit of stuff.

@David would encourage you to take a look at http://drupal.org/project/apachesolr_views . This project ties into the facet blocks allowing for that to happen. Just need to have the 'facet' either as an exposed filter or an argument

janusman’s picture

@dave, re #3: I was speaking of *just* the case where the facets are taxonomy terms, since we're essentially using Drupal data to show the terms and perhaps their lineage (Solr stores only the term ids); but I was missing the scenario where these blocks were populated as a result of a search (internal or user-started) which, of course, can't be done with Tagdelic.

Are we aiming to show these blocks somehow filtered to facets after a search result? Or just something like tagadelic (showing the complete available facet values for a facet, with no filtering? I find it hard to come up with a use case for the former.

Thanks for the time =)

david lesieur’s picture

@Scott: I will check ApacheSolr Views, for sure! Views and Solr, an incredible combination!

@janusman: Yes, the facets should be filtered to only show values that are relevant to the current result set. If your current result set does not have any node with tag A, I don't see any reason for listing A in the facet block as it would not help refine the search. The great thing is: this is already what happens in ApacheSolr. :-)

janusman’s picture

Sorry to insist with questions, I just want to get my involvement right =)

@david: I'm thinking this is a complete duplicate of #358166: Search for just facet(s) as that issue's goal is to *start* a full-fledged apachesolr search with just a facet value and no keys... I still don't understand what's different?

Perhaps the "different" portion of this issue is showing a "start browsing" page like this? http://www.peb.com.mx/faceted_search/ ... however those facets are not limited and represent the whole node corpus.

david lesieur’s picture

@janusman: I have seen the description of your latest patch, and it now seems closer to what I'm looking for. I'll certainly check the patches in #358166: Search for just facet(s) before coding anything about this.

I need the facet blocks to be displayed on any page, not just on the search page. So unless that case is already covered by #358166, this is not a duplicate. However, #358166 could be considered a prerequisite to #442976.

Scott Reynolds’s picture

Ok so I achieve this though Im not happy about it yet. It takes a node/NID page and runs a query that loads up the facet blocks for the nodes terms. The links to go back work.

Basically, the approach is to have apachesolr, on hook_init() execute a query so apachesolr_has_searched() is true and there is a valid search that happened. My approach using my apachesolr_views but it uses standard apachesolr facet blocks.

/**
 * Implementation of hook_init().
 */
function mc_init() {
  // use menu_get_item() to fetch the node
  $router = menu_get_item();
  if (is_array($router['load_functions'])) {
    foreach ($router['load_functions'] as $position => $function) {
      if ($function == 'node_load' && !empty($router['map'][$position])) {
        $tags = array(implode(",", array_keys($router['map'][$position]->taxonomy)));
        // grab the View and execute it.
        // need to use preview, as you can't pass in arguments any other way
        // cause the $view->build will parse arguments from the url
        // calling $view->pre_execute($args = array()) won't work either
        // as that relies on a display handler being active
        // thus we be stuck
        // also we need a display_id so the links generated by the blocks make sense
        $view = views_get_view('conversations');
        $view->preview(MC_CONVERSATIONS_PAGE, $tags);
      }
    }
  }
}

It is using apachesolr_views to do the query but all the facet blocks work. The same thing can be done with apachesolr standard.

I hope this gets you started.

david lesieur’s picture

Assigned: Unassigned » david lesieur
Status: Active » Needs work
StatusFileSize
new1.25 KB

Played with this a bit, executing the search in apachesolr_search_block() if it has not been executed before.

To try this, first apply the patch in Search for just facet(s), then the one below.
Still needs work, if only to prevent the blocks from appearing everywhere by default (per pwolanin's suggestion in #1).

Scott Reynolds’s picture

Thats not where you want to invoke it. It becomes a race between who's hook_block() gets called first. You want it in hook_init(), and you probably want it configurable.

david lesieur’s picture

Right, there's a huge flaw here. Perhaps the part that's missing is checking the block delta to execute the search only if we're really dealing with an apachesolr_search block.

I'm a bit wary of hook_init(), afraid to perform a search in some cases where it is not necessary, as it is really required only on a search page or when a facet block is actually visible.

Then there is also the problem of apachesolr_has_searched() and apachesolr_static_response_cache() allowing only a single search. I'm afraid we'll soon want to be able to perform multiple searches per page request, but that would be a separate issue. IMO it should be perfectly legitimate to have an apachesolr_search facet block on an apachesolr_views page even though these would be separate searches.

Scott Reynolds’s picture

Right, there's a huge flaw here. Perhaps the part that's missing is checking the block delta to execute the search only if we're really dealing with an apachesolr_search block.

lost me there. Why would you want it to only work with apachesolr_search block.

I'm a bit wary of hook_init(), afraid to perform a search in some cases where it is not necessary, as it is really required only on a search page or when a facet block is actually visible.

like in my example, it only performs searches on node/NID pages. You can do something similar based on loading up the block and checking the visibilty settings. I believe the blocks are static cached so there is no db queries thats really added.

Then there is also the problem of apachesolr_has_searched() and apachesolr_static_response_cache() allowing only a single search. I'm afraid we'll soon want to be able to perform multiple searches per page request, but that would be a separate issue. IMO it should be perfectly legitimate to have an apachesolr_search facet block on an apachesolr_views page even though these would be separate searches.

That happens already. The response is exactly the same. The apachesolr_current_query() returns an object that implements Drupal_Solr_Query_Interface which both the standard Solr does, and apachesolr_views. So all the facet blocks work. I do not think there is a need to make these store multiple.

david lesieur’s picture

Why would you want it to only work with apachesolr_search block.

I have assumed that apachesolr_search's facet blocks were always to be based on apachesolr_search's query. So I guess I have missed the apachesolr_views case... In that case, you currently have the facet blocks using the response obtained for the views' query, right?

I do not think there is a need to make these store multiple.

What if I need two facet blocks on the same page, each block relating to a different search? If facet blocks are to be displayable anywhere (i.e. outside a conventional search page), this could be a legitimate need.

Scott Reynolds’s picture

all facet blocks expect for sorts #443410: Apachesolr Sort block doesn't integrate with this module. And this is because Views doesn't have a concept of exposed sorts. But its rumoured that its being worked on in the recently branched, Views3.

david lesieur’s picture

Ok, here are the main problems that I understand:

  • Whether apachesolr_search runs its query in hook_init() or hook_block(), it will be competing against other modules such as apachesolr_views that might want to run their own query first.
  • If a facet block appears on a page that's neither a search nor a view page, which query should we run?

Possible solutions... thinking out loud:

  • The patch in #10: If apachesolr_views (or another module) runs its query in its hook_init() implementation, then the facets will be based on that query's response because it ran first. In other words, the facets will relate to whatever query became The Current One. However, if no query has been run when the facet blocks get displayed, apachesolr_search's query will be executed (kind of as a fallback). Not so satisfactory...
  • Create a registry where each module would advertise its queries (one query for apachesolr_search, one for each apachesolr view). Create a path-based configuration for site admins, where selected queries would run on specified paths. Still limited to a single query per page. On non-configured paths, I guess we'd either fallback to an apachesolr_search query or show no facet block at all.
  • Create a registry where each module would advertise its queries (as above). Facet blocks would be "instanciated" on demand by admins, and each block mandatorily associated to a query. Each block would know what query to execute if it gets displayed and the query has not been executed yet. Responses would be cached for multiple queries. Different facet blocks on the same page could therefore relate to different queries.

The latter two ideas seem to solve the problems I have outlined, and allow multiple search sections on the same site. However, the last one is more flexible and looks cleaner to me.

Opinions? Better ideas?

david lesieur’s picture

To put the idea more simply: Have each facet block know what query to execute. If the block gets displayed and the query has already executed, fine, use the cached response. If it has not been executed, have the block request its execution. If a facet needs to be used with a different query depending on context, add a new instance of that facet's block and associate it to the right query.

Scott Reynolds’s picture

Still confused here. So Im going to take an implementation stab here. Lets say on standard node View page of type = 'page' you want to display the taxonomy facet block with fq=type:page.

On init(), check to see if !apachesolr_has_searched() and url matches the View (Views has a static cache as well something like current_view()). If it does, run a apachesolr search.

So basically, you need a way to set up those rules. The facet blocks shouldn't care what type (standard, local solr, apachesolr_views) the query is.

This doesn't feel like something that belongs in apachesolr.module.

david lesieur’s picture

Perhaps I'm confused too, but it seems that the main difference between our two approaches is that you favor setting up per-page rules for running the searches, whereas I'm proposing per-block rules.

brant’s picture

Subscribing -- any movement here (or elsewhere) on a solution for this? It would be great to allow faceted browsing using Solr.

janusman’s picture

@brant: Maybe these alternatives *might* be of some use:

The 2.x branch already has some options to show "browse by" blocks at the search start page (/search/apachesolr_search)

As an alternative you can also use taxonomy_menu to show taxonomy blocks (expandable if you use DHTML_menu module or the like) you can place anywhere, that will lead to an ApacheSolr search if you enable "Use Apache Solr for taxonomy links" under the Advanced configuration fieldset in admin/settings/apachesolr/settings.

pwolanin’s picture

Status: Needs work » Closed (won't fix)
pwolanin’s picture

Version: 6.x-1.x-dev » 7.x-1.x-dev
Status: Closed (won't fix) » Active

So, for 7.x-1.x (and 6.x-3.x) this sounds like what EclipseGC suggested was possible w/ Views context + panels.

I don't think it's something we should directly support.

pwolanin’s picture

Status: Active » Fixed

We already have the facet browsing working in 7.x

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

gaëlg’s picture

For D6, you can use something like this in a hook_init to send a query to Solr so that facet blocks can be displayed on any page ($query and $response will be saved as static variables) :

function MYMODULE_empty_search($base_path = '', $filterstring = '') {
  //Based on apachesolr_search_execute
  $query = apachesolr_drupal_query('', $filterstring, '', $base_path);
  $params = apachesolr_search_basic_params($query);
  if (!apachesolr_server_status()) {
    apachesolr_failure(t('Solr search'), $filterstring);
    return FALSE;
  }
  apachesolr_search_add_facet_params($params, $query);
  apachesolr_do_query('apachesolr_search', $query, $params);
  apachesolr_has_searched(TRUE);
  return TRUE;
}
yosifumi’s picture

hi all,

I am using Apache Solr Search Integration 7.1.2, facet api 7.1.3 with solr 4.0? ( opensolr service ).

I can not see facet block in non-search page even-though I set up

/admin/config/search/apachesolr/settings/solr/facets?destination=admin/config/search/apachesolr/settings

Non-search paths
node
node/*
content/*
user/*

and
/admin/config/search/apachesolr/search-pages/core_search/edit

advanced option
[x]Show enabled facets' blocks in their configured regions and first page of all available results

when i hit search button with no key words, it returns

Please enter some keywords.

hope any solution.

best,
yoshi

yosifumi’s picture

Version: 7.x-1.x-dev » 7.x-1.2
Assigned: david lesieur » Unassigned
Status: Closed (fixed) » Active

May I change the status?