I wrote a patch that allows to reflect a hierarchical taxonomy vocabulary in a facet.

It adds a checkbox to the facet's corresponding block configuration. Using this checkbox you can decide if a facet flattens a hierarchical taxonomy vocabulary like it's currently implemented in beta5 or if the facet reflects the hierarchy.

If you choose to reflect the hierarchy you'll see only top level terms in the first step. If you click on such a top level term, the search result gets filtered and the child terms of that top level term having results will appear.

Note:
While working on this patch I ran into an existing bug in beta5 which was already posted here: #400882: Apache Solr does not always filter down
I fixed that one and decided to attach the fix to that bug report. So before trying this new feature you have to apply my patch that fixes that bug first.

CommentFileSizeAuthor
#160 apachesolr-hierarchical-taxonomy-401234-D5.patch19.36 KBclaudiu.cristea
#158 taxo-hierarchy-6-2.patch18.96 KBrobertDouglass
#157 taxo.jpg21.05 KBrobertDouglass
#152 taxo-new-401234-152.patch17.93 KBpwolanin
#151 taxo-new-401234-151.patch17.9 KBpwolanin
#146 401234-146.png123.14 KBjanusman
#145 taxo-new-401234-145.patch16.09 KBpwolanin
#143 taxo-new-401234-143.patch16.05 KBpwolanin
#140 401234-140.jpg92.46 KBjanusman
#140 apachesolr-401234-140.patch15.72 KBjanusman
#139 apachesolr-401234-139.patch15.41 KBjanusman
#137 401234-137-1.jpg10.56 KBjanusman
#137 401234-137-2.jpg59.97 KBjanusman
#134 taxo-new-401234-134.patch15.9 KBpwolanin
#132 taxo-new-401234-132.patch15.1 KBpwolanin
#131 taxo-new-401234-131.patch14.52 KBpwolanin
#129 apachesolr-401234-129-wip.patch16.56 KBpwolanin
#120 apachesolr-401234-120.patch16.17 KBpwolanin
#119 apachesolr-401234-119.patch16.24 KBpwolanin
#102 apachesolr-401234-101.patch13.92 KBjanusman
#91 apachesolr-401234-91.patch14.83 KBjanusman
#89 apachesolr-401234-89.patch16.17 KBjanusman
#83 apachesolr-401234-83.patch15.48 KBjanusman
#82 apachesolr-401234-82.patch15.49 KBjanusman
#76 apachesolr-401234-76.patch15.7 KBjanusman
#73 apachesolr-401234-73.patch15.42 KBjanusman
#70 apachesolr.hierarchical_facet.patch15.53 KBmkalkbrenner
#69 apachesolr-401234-69.patch16.33 KBjanusman
#60 401234_60.png40.05 KBjanusman
#59 apachesolr.hierarchical_facet.patch11.68 KBmkalkbrenner
#57 apachesolr.hierarchical_facet.patch11.57 KBmkalkbrenner
#54 apachesolr.hierarchical_facet.patch11.58 KBmkalkbrenner
#50 apachesolr.hierarchical_facet.patch11.67 KBmkalkbrenner
#49 proposed-presentation-unlimited-4.png204.04 KBFrancewhoa
#42 apachesolr.hierarchical_facet.patch11.71 KBmkalkbrenner
#41 apachesolr.hierarchical_facet.patch11.22 KBmkalkbrenner
#38 apachesolr.hierarchical_facet.patch11.12 KBmkalkbrenner
#33 apachesolr.hierarchical_facet.patch10.24 KBmkalkbrenner
#30 401234_30.patch9.69 KBjanusman
#25 401234_25.patch8.89 KBjanusman
#25 401234_25.png4 KBjanusman
#22 apachesolr.hierarchical_facet_6.patch10.91 KBjanusman
#20 apachesolr.hierarchical_facet.patch10.62 KBmkalkbrenner
#15 apachesolr.hierarchical_facet.patch10.71 KBmkalkbrenner
#12 fig4.jpg142.64 KBcoupet
#8 apachesolr.hierarchical_facet.patch10.11 KBmkalkbrenner
#6 hierarchic_terms_facets_problem.jpg33.75 KBjanusman
#5 apachesolr-401234.patch9.01 KBjanusman
#4 apachesolr.hierarchical_facet.patch9.19 KBmkalkbrenner
#3 apachesolr.hierarchical_facet.patch9.19 KBmkalkbrenner
#1 hierarchic_terms_facets.jpg21.23 KBjanusman
apachesolr.hierarchical_facet.patch9.18 KBmkalkbrenner
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

janusman’s picture

FileSize
21.23 KB

Very Nice!!!

Attached screenshot comparing before/after. SO much better =)

Two things:
* Could you please submit a patch against DRUPAL-6--1 (dev)
* It seems somehow the character you tried to use inside theme_apachesolr_facet_item_indent() didn't get through (My editor in UTF mode shows it as just "?"). Could you try another character or sending the patch as UTF?

function theme_apachesolr_facet_item_indent($indent = 0) {
  if ($indent > 0) {
    return str_repeat('  ', $indent) .' » '; // I replaced the ? char with »
  }
}
janusman’s picture

Status: Needs review » Needs work
mkalkbrenner’s picture

Version: 6.x-1.0-beta5 » 6.x-1.x-dev
Status: Needs work » Needs review
FileSize
9.19 KB

Thank you for the screenshot!

It seems that special UTF-8 characters break somewhere during the upload process. The char I used was "∟".
Nevertheless I included your theme function and recreated the patch against DRUPAL-6--1 (dev).
Due to the fact that indention is realized using a theme function everyone could decide for himself how indention should look like.

mkalkbrenner’s picture

Something went wrong again: ' » '

I choose ' > ' now to be on the safe side.

janusman’s picture

FileSize
9.01 KB

Confirm patch works. However, it added/removed some blank lines; re-rolled against latest DEV.

Also, maybe could we do better than >? =)

janusman’s picture

Just noticed that this needs to be attacked in the "Current search" block too, as hierarchy isn't being reflected.

E.g. after drilling down thru "Fruit" > "Apples" > "Red delicious", the current search block doesn't show this hierarchy, and then you can remove parent facets (e.g. "Fruit") and end up with children facets active (e.g. "Red Delicious"). This also causes the new hierarchic view to go nuts also. See attached screenshot.

janusman’s picture

Status: Needs review » Needs work
mkalkbrenner’s picture

Status: Needs work » Needs review
FileSize
10.11 KB

@janusman:

You're right. I adjusted the patch to reflect the hierarchy in current search block as well.
But I decided to not visualize the hierarchy in current search block. Only unlink links are constructed the right way now if you decide to turn on hierarchy on a facet block.

BTW I fixed a small sorting bug in hierarchical facet blocks as well.

jarchowk’s picture

There is a bug in this where if you delete a taxonomy term after the tid is indexed it bombs out the screen.

Also the $vid is hardcoded at substring pos of 7. Mine needs to be 12 for whatever reason (older version?), is it possible to not rely on substring?

mkalkbrenner’s picture

@jarchowk:
I didn't introduce "substring pos of 7", I just moved the according line in my patch.
I'll have a look at the code to see if it's robustness against deletion of tids could be improved.

But from my point of view both points a general issues for apachesolr module and not related to this patch.

pokadan’s picture

+1 for this to make it in the next apachesolr release
I ran into the small sorting bug mkalkbrenner was talking about myself (http://drupal.org/node/412332); one more reason for it to make it in the next rel

coupet’s picture

FileSize
142.64 KB

See attached example. The metadata conditions can be easily explored by opening and closing the subtrees without selecting them.

mkalkbrenner’s picture

@coupet:
Could you please explain your posting more detailed? Did you find a better solution for hierarchical taxonomy in facets? Or do you want to have this patch to work like the screenshot you attached?

coupet’s picture

@ mkalkbrenner:

Suggesting for the patch to work as shown in screenshot.

mkalkbrenner’s picture

@ #9 jarchowk:
I found a bug regarding removed tids. Could you please test again?

The patch should be applied against snapshot 6.x-1.x-dev 2009-Apr-16 now.

Glenmoore’s picture

Hi, could you tell me if this patch is likely to work against the 6.11 release?
If so, can you confirm that it was written relative to the Modules directory NOT the root directory?
Many thanks

mkalkbrenner’s picture

@Glenmoore:

The patch works with drupal 6.11. And it should be applied against apachesolr module directory.

BTW the patch fails with current dev snapshot. I'll fix that soon.

Glenmoore’s picture

@mkalkbrenner
Hi I am running Beta 5 so applied your 'clone' patch for this version which seemed to change the file as required (though I received no 'successful' or 'failed' messages-but the code looked like it had changed as expected). However, when I checked that my Apache search was still working I received the following WSOD message.

Fatal error: Class 'Solr_Base_Query' not found in C:\wamp\www\drupal2\sites\all\Modules\apachesolr\apachesolr.module on line 856

Now, I also tried to apply a patch yesterday to ApacheSolr which also appeared to be successful but resulted in a different WSOD so I may be doing something wrong. Let me tell you what I did and maybe you can spot the error.

I uploaded the patch file into Wordpad and saved as a text doc (as I am using Windows)
I placed the patch file inside the apachesolr file, navigated to the apachesolr file and typed "patch -p0 < Solr_Base_Query.php_.clone_.patch" in Cygwin.

Reversing the patch ("patch -p0 -R < Solr_Base_Query.php_.clone_.patch") does not get rid of the problem. I have to replace the Solr_Base_Query.php file completely before the problem goes away.

Sorry, wasnt sure if this should be posted on the thread which started with the patch in question (but decided to post it here as my primary objective is to apply the 'hierarchical' patch) apologies if it should.

pwolanin’s picture

Status: Needs review » Needs work

according to above comments, patch doesn't apply.

Also, looks to me like there is too much being hard coded here - does this really need to be in the main module, or can an add-on module achieve this output?

mkalkbrenner’s picture

Status: Needs review » Needs work
FileSize
10.62 KB

Glenmoores comment above doesn't indicate that the patch could not be applied. The problem there is that he mixed an old version of apachesolr module (beta5) another patch and this patch.

Here's the patch to be applied against apachesolr 6.x-1.x-dev 2009-May-07.

I'm of the opinion that this feature should get into apachesolr directly because flattened hierarchical vocabularies behave really strange and unpredictable for the user. See #412332: order change for facet item list.
The implementation is comparable to the "Include missing facets" feature. It's not to much code but it rearranges a bigger part of hook_block of apachesolr_search.module. For Example it moves up

$vid = substr($delta, 7);
if (is_numeric($vid)) {

which is more efficient and fixes small issues like trying to load a vocabulary with a non numeric vid.

If I move this feature into a separate module I'll have to copy and modify a lot of code which isn't best especially it's hard to keep it in sync with apachesolr.

mkalkbrenner’s picture

Status: Needs work » Needs review
janusman’s picture

Status: Needs work » Needs review
FileSize
10.91 KB

It works. But...

I'm thinking we should really use theme_item_list() specifically defining children of other items... e.g.:

theme('item_list', array('data' => 'fruit', 'children' => array('apples', 'oranges')));

This should also then work with date facets, for instance.

However, this is IMO, I think the patch could go on as is for now until we get a more elegant solution? Opinions?

mkalkbrenner’s picture

Status: Needs review » Reviewed & tested by the community

"However, this is IMO, I think the patch could go on as is for now until we get a more elegant solution?"

I would highly appreciate that because it's a lot of work to keep this patch in sync with the ongoing changes within the apachesolr module.
If this patch will be accepted I'm willed to keep improving it.

pwolanin’s picture

Status: Reviewed & tested by the community » Needs work

as above, this needs to be done in a more generic way versus hard-coding it to taxonomy. I'd rather see more serious if necessary to support such a feature.

janusman’s picture

Status: Needs work » Needs review
FileSize
4 KB
8.89 KB

Here's a patch that builds an array of children term elements to go into theme_item_list; this does away with the "indent" functions.

Attached screenshot of how it looks.

BTW looked around and couldn't find a better solution than using eval() to build the array programatically (which feels like a hack); suggestions welcome.

pwolanin’s picture

Here's a patch (complete I hope) to do some clean-up of the facet code/theme functions: http://drupal.org/node/463900#comment-1593394

That might help simplfy the changes needed here. If not, please suggest additional improvements.

@janusman - why is the eval() needed at all?

janusman’s picture

@pwolanin: the eval() helps build the nested array of items to later pass on to theme_item_list(). It's a fast way to add items to existing portions of the array at any depth; I can't find (yet) how PHP could handle passing pointers to array elements--I don't think it can.

I just thought that eval() might not be secure in this case if a facet value includes an apostrophe. So that would have to be fixed.

Is it ok to keep this approach (just adding the above security check) and just reissue a patch when #463900: facet theme function clean-up is done? Or, what's missing?

pwolanin’s picture

@janusman - you can certainly have references to array elements, and maybe I'm misunderstanding what you are trying to do. For a use of array elemnt references in core see: http://api.drupal.org/api/function/menu_tree_collect_node_links/6

janusman’s picture

Status: Needs review » Needs work

I am realizing that, yes, *I am not sneaky enough* =)

Will write or adapt a recursive function to do the job without eval().

Good starting point:
http://kevin.vanzonneveld.net/techblog/article/convert_anything_to_tree_...

janusman’s picture

Status: Needs work » Needs review
FileSize
9.69 KB

Ok, new patch, does not use eval().

mkalkbrenner’s picture

Status: Needs review » Needs work

I confirm that janusman's patch from #30 works and solves indention more elegant than my original version.

What's left to do now is to combine it with pwolanin's cleanup patch: #463900: facet theme function clean-up

janusman’s picture

@mkalkbrenner: I'd say this is RTBC... have to take this one patch at a time =)

mkalkbrenner’s picture

@janusman:
Your latest patch contains a bug. It breaks hidden item functionality because theme_apachesolr_facet_list() doesn't deal with the new children element.
Attached you find your patch with a small adjustment for theme_apachesolr_facet_list():

@@ -1372,8 +1383,8 @@
     drupal_add_js(drupal_get_path('module', 'apachesolr') . '/apachesolr.js');
     // Split items array into displayed and hidden.
     $hidden_items = array_splice($items, $display_limit);
-    foreach ($hidden_items as $link) {
-      $items[] = array('data' => $link, 'class' => 'apachesolr-hidden-facet');
+    foreach ($hidden_items as $hidden_item) {
+      $items[] = $hidden_item + array('class' => 'apachesolr-hidden-facet');
     }
   }
   $admin_link = '';
mkalkbrenner’s picture

Status: Needs work » Needs review
pwolanin’s picture

looks liek there are some code style issues in the changed code in terms of whitespace.

Also, I'm not sure I understand why we need the static cache and what this function is really doing:

  function apachesolr_get_unclick_link(&$query, $field_name, $field_value, $vid = FALSE) {

I'ts taxonomy specific?

mkalkbrenner’s picture

@pwolanin:
For non hierarchical facet items you simply remove current term's tid from the url to get an unclick link. But in case of hierarchical vocobularies unclick links become more complicated. If you unclick a parent item you have to remove tids of all children, too. I decided to put this extra logic into a separate function because unclick links are build at different places.

The reason for the static caching of unklick links is that the same unclick links are used in different places, for example in a facet block based on a hierarchical vocabulary and in the current search block .

BTW I even noticed that:

 function apachesolr_get_unclick_link(&$query, $field_name, $field_value, $vid = FALSE) {
  ...
  $path = 'search/' . arg(1) . '/' . $new_query->get_query_basic();
  ...
}

I think that the way to create the path changed in CVS since the first version of this patch. I'll adjust that ...

pwolanin’s picture

I feel like I am missing something here,
can you explain and maybe illustrate the
desired final behavior.

mkalkbrenner’s picture

I fixed path handling and added some comments to the patch to explain unclick link creation.

pwolanin’s picture

I still would like a clear summary of the goal - which links are supposed to appear when, how are unclick links supposed to work, etc. I can't really review the patch without that.

mkalkbrenner’s picture

hierarchical vocabulary 1:

1
2
  3
  4
    5
6

non hierarchical vocabulary 2:

7
8
9

Now some examples about unclick links.

current search:
tid:1 tid:7 type:story
unclick Links:

remove tid:1 => tid:7 type:story
remove tid:7 => tid:1 type:story
remove type:story => tid:1 tid:7

current search:
tid:2 tid:3 tid:7 type:story
unclick Links:

remove tid:2 => tid:7 type:story
remove tid:3 => tid:2 tid:7 type:story
remove tid:7 => tid:2 tid:7 type:story
remove type:story => tid:2 tid:3 tid:7

3 is a child of 2. So if 2 is removed from query, 3 must be removed, too.

current search:
tid:2 tid:3 tid:4 tid:5
unclick Links:

remove tid:2 =>
remove tid:3 => tid:2 tid:4 tid:5
remove tid:4 => tid:2 tid:3
remove tid:5 => tid:2 tid:3 tid:4

3,4 and 5 are children of 2. So if 2 is removed from query, all children must be removed, too.
5 is a child of 4. So if 4 is removed from query, 5 must be removed, too.
But note that 3 is a sibling of 4 and does not affect 5.

mkalkbrenner’s picture

issue / patch from comment #33 doesn't work for some cck fields. Attached you find a patch containing a safer version:

-    foreach ($hidden_items as $link) {
-      $items[] = array('data' => $link, 'class' => 'apachesolr-hidden-facet');

+    foreach ($hidden_items as $hidden_item) {
+      if (!is_array($hidden_item)) {
+        $hidden_item = array('data' => $hidden_item);
+      }
+      $items[] = $hidden_item + array('class' => 'apachesolr-hidden-facet');
mkalkbrenner’s picture

I adjusted the patch to work with apachesolr development snapshot 6.x-1.x-dev 2009-Jun-19.
In other words I applied the api changes from #463900: facet theme function clean-up.

Please note that this patch won't work until issue #496650: Unclick links don't work in 6.x-1.x-dev 2009-Jun-19 is fixed (simply apply the patch available there first).

BTW hierarchical facets are very suitable for filters by forum topic.

Francewhoa’s picture

Great feature. Subcribing.

robertDouglass’s picture

I don't want to derail this very nice feature but I do want people to join me in thinking about ways to make facet block display pluggable (as well as the logic behind it all). for example, I've come up with two alternate ways to display facets (tag clouds and bar graphs) that will sit nicely alongside this hierarchical display and the normal facets. It would be nice if we could generalize how the admin chooses displays and how the system handles them. Investigating this patch might be a source for inspiration to this end.

Nice work so far here. My read of the patch didn't uncover anything obvious, so I need to test it thoroughly before commenting further.

pwolanin’s picture

I'm am unhappy with the use of this function for all facets:

+function apachesolr_search_get_unclick_link(&$query, $facet_text, $field_name, $field_value, $vid = FALSE) {

It seems to add unneeded overhead and complexity for the common case.

As Robert suggests above, we possibly need a way to add information for each facet block about a display handler. So, Basically the functions for display hierarchical vocab facets would substitute for the current ones.

This is starting to sounds a bit like a views block display handler, at least in concept.

For the short term, possibly we could add a link next to each enabled facet to take you to chooser?

janusman’s picture

@mkalkbrenner: great you're looking into this, will test it soon!

Now, re: #44, #45...

Thinking in this more general framework, IMO this patch is about improving the current "facet block display handler" which turns out to be the one for "taxonomy".

I agree 100% with trying to build a flexible framework for facets (display handlers, hooks, etc); and yes, it starts to sound a bit like views =) In fact at DrupalCon DC I suggested to @afummy that maybe, ApacheSolr could just be the backend for Views, and Views UI could behave like faceted search (where all options shown to "filter down" indeed produce >0 search results)... just an idea =)

However, IMO @robertDouglass's #44 and @pwolanin's (and my) agreement on it is farther down the road; if not we will get this module to final 1.0 in another 12 months =)

Can I convince you to move this issue ahead and open a new one to look into more into the facet framework (?) for Apache Solr?

robertDouglass’s picture

Like I said, I wasn't trying to derail this feature.

@janusman - apachesolr_views module makes Solr the backend for views. It works, pretty much like you describe.

Francewhoa’s picture

I'm want to contribute testing for the patch in comment #42. But the patch didn't work. Is it normal?

First I apply unclick.patch. Terminal returns

patch: **** Only garbage was found in the patch input.

Then I apply apachesolr.hierarchical_facet_10.patch. Terminal returns

patching file apachesolr.module
Hunk #3 succeeded at 1405 (offset -1 lines).
patching file apachesolr_search.module

Then when trying a Solr search at mywebsite.com/search/apachesolr_search/ Drupal returns the below error. It was working fine before the patch.

Fatal error: Call to undefined function apachesolr_search_localize_taxonomy_term() in /home/mydomainname/public_html/sites/all/modules/apachesolr/apachesolr_search.module on line 602

Things I tried: Rebuilding Solr index, run cron.php then wait 5 minutes before testing again.

I'm using Ubuntu Server 8.04.2 via SSH. Patches applied against current head apachesolr-6.x-1.x-dev.tar.gz 2009-Jun-19.

Francewhoa’s picture

I'm assuming that this patch indent the children facets. It's a great feature. It improves usability.

I suggest another improvement to the current patch. Adding an unlimited facet depth instead of the current limited depth. Find attached screenshot to clarify. The unlimited depth is use with the Faceted Search module. You can try it at: http://facetedsearch.davidlesieur.com
This demo uses unlimited facet depth so you'll still see only top level facet in the first step. If you click on it, the search result gets filtered and the child facet of that top level term having results will appear. Clicking the 'all' link brings you back to the top level facet. Notice the use of two colours: Grey for not clickable items such as arrows and (number) and red for the facets. Using two colours make the block easier to read and looks better.

The issue with patch #42 is that if the Solr block is 200 pixels width fixed. The depth is limited to 3 or 4 facets maximum. With 5 facets depth or more the fixed block might not be wide enough and the facets will start distorting the block and the website design/layout.

With suggested unlimited facet depth if the Solr block is 200 pixels width fixed the depth is unlimited. When the facet reach the right side of the block it simply continue on the next line and so on. Unlimited. Works for both fixed and expendable/fluid design. Find attached mockup to clarify. This is how the suggestion works.

mkalkbrenner’s picture

@#48 Onopoc:
Sorry, the error you ran into was a remaining change from #436578: Translated (localized) taxonomy facet blocks and #463886: localize apachesolr date formats I'm working on. I attached a corrected patch against apachesolr development snapshot 6.x-1.x-dev 2009-Jun-20 which already includes #496650: Unclick links don't work in 6.x-1.x-dev 2009-Jun-19. Please try again.

@robertDouglass, janusman, pwolanin:
Introducing facet handlers or a plug in infrastructure sounds good to me. But I second janusman and suggest to apply this patch to CVS now and start working on the api changes afterwards.
For me it's pretty hard to keep this patch in sync with all the changes happening to apachesolr for three and a half months now.
We already use apachesolr in production right now and I'm forced to keep this patch in sync because normal taxonomy facets are unusable for our hierarchical vocabularies.
I'm willed to keep improving this feature in future (p.e. #12, #45, #49 or "missing facets" which are marked as TODO in cvs), but it will be much easier and cost less time if a first version is in CVS.

pwolanin’s picture

Status: Needs review » Needs work

I'll try to review in depth today. I see some obvious problems though, mostly style/readability. Like:

$link = apachesolr_search_get_unclick_link($query, $term->name, 'tid', $tid, $reflect_hierarchy['apachesolr_search'][$delta] ? $vid : FALSE);

apachesolr_search_get_unclick_link is only really operative for hierarchical taxonomy, right? The use of the ternary operator in the funciton call is hard to follow, and really it doesn't make sense to me to ever call this new function unless we are representing a hierarchy. So, I'd rather see code more like:

if ($reflect_hierarchy['apachesolr_search'][$delta]) {
  $link = apachesolr_search_get_hierarchical_unclick_link($query, $term->name, $tid, $vid);
}
else {
  $link = theme('apachesolr_unclick_link', $term->name, $new_query->get_path(), $options);
}

The current special case of $vid and 'tid' could then just be the code that always runs in apachesolr_search_get_hierarchical_unclick_link().

mkalkbrenner’s picture

@#51 pwolanin:

I'm fine if you decide to modify the code this way.

My intention was to move redundant code to that function:

$new_query = clone $query;
$new_query->remove_filter($field_name, $field_value);
...
$options['query'] = $new_query->get_url_querystring();
$unclick_links[$field_name][$field_value] = theme('apachesolr_unclick_link', $facet_text, $new_query->get_path(), $options);

Additionally every unclick was build two times (including query cloning and sometimes taxonomy tree) if current search block is activated. That's why I introduced the cache within this function in general.

Another approach might be to keep this function and the cache but hand over an array containing an already build list of filed_name and field_value pairs to be removed from current query. Than we have a common function that others might use, too.

Than your example will look somehow like this:

$to_be_removed = array(array('name' => 'tid', 'value' => $tid));

if ($reflect_hierarchy['apachesolr_search'][$delta]) {
  $childs = taxonomy_get_tree($vid, $tid);
  foreach ($childs as $child) {
    $to_be_removed[] = array('name' => 'tid', 'value' => $child->tid));
  }
}

$link = apachesolr_search_get_unclick_link($query, $to_be_removed);
pwolanin’s picture

This second option of a more generic function looks more useful/re-useable to me.

In terms of performance, I doubt this 2x cloning has measureable effect on page load, and also this might lead to problem if one wants to do for example, a federated search (e.g. separate user and ndoe searches shown on the same page). In the absence of compelling evidence that this optimization is needed, I think it should be omitted.

In terms of actual performance, I'd bed the Frankenstein use of page_query() is more of an issue, since I'd think this issues a couple actual SQL queries which do essentially nothing.

mkalkbrenner’s picture

Status: Needs work » Needs review
FileSize
11.58 KB

I adjusted the patch according to my new approach from #52.

Caching is still included but could be removed if you like to.

pwolanin’s picture

Why not just do:

$remove[] = $field;

instead of:

$remove = array(array($field['#name'], $field['#value']));

Then you can reference the named keys instead of 0, 1

mkalkbrenner’s picture

For current search block you're right. But for im_vid_ blocks we would have to create those $field arrays. Same for date facet block if we migrate it.

My intention was to find an easy way to hand over a list of key value pairs where same key might be present multiple times and that could be easily serialized to generate a cache key no matter in which order these key value pairs are passed.

mkalkbrenner’s picture

Adjusted patch to latest api changes introduced by #502976: Other GET parameters ignored by Apache Solr Facet Blocks.
Patch is against apachesolr 6.x-1.x-dev 2009-Jul-03.

pwolanin’s picture

I still think we should be using named keys vs. 0, 1

mkalkbrenner’s picture

Here's a reworked version that uses '#name' and '#value' as named array keys instead of 0 and 1.

janusman’s picture

Status: Needs review » Needs work
FileSize
40.05 KB

Patch applies cleanly to fresh checkout.

It works, however, if the user is directly limiting by a deep-levelled term (which will happen if "Use Apache Solr for taxonomy links" in admin/settings/apachesolr/settings is set), then the "Filter by" facet block fails to show the lineage (it just shows the top-level parent as available).

See attached image: on the left is the result of normal search + filtering; on the right is what would happen if I would click on the term "Economics" from inside a node's taxonomy term links, or if a user somehow has a direct link to that term.

mkalkbrenner’s picture

I think the issue janusman reported was introduced by #472600: Replace taxonomy/term/XXX node listings with Apache Solr search results.
I'll work on it, but only if I get pwolanin's commitment to accept the patch. Otherwise it's just a waste of time.

robertDouglass’s picture

mkalkbrenner this issues has been slated to still go into the 6.1 branch - you won't be wasting your time.

janusman’s picture

@mkalkbrenner: need help? =) Contact me or leave a note here.

mkalkbrenner’s picture

@janusman:
Thanks for your offer. My current problem is, that we're busy with two projects going live this week. So if you have some free time it would be nice if you take this task. Otherwise I'll do it next week.

I see two approaches, which should be discussed here:
1. Specific: Apply some additional logic when creating taxonomy links to also add parent tids in case of hierarchical vocabularies.
2. General: Detect missing tids in case of hierarchical vocabularies on search result page and send a redirect with a corrected url.

Do you see another approach?

janusman’s picture

Assigned: mkalkbrenner » janusman

@mkalkbrenner: Those pesky projects, eh? =) Good luck on that.

I prefer (1). I think the code should always try to build the lineage every term if it hasn't already.

E.g. Fruit (tid:1) > Apples(tid:2) > Granny smith(tid:3)

Case 1) filters=tid:3
Build the lineage for all parent terms of tid:3

Case 2) filters=tid:1 tid:3
Build lineage for tid:1
Build lineage for tid:3 (add tid:2 as son of tid:1, add tid:3 as son of tid:3)

Case 3) filters=tid:1 tid:2 tid:3
Build lineage for tid:1
Build lineage for tid:2 (add tid:2 as son of tid:1)
Build lineage for tid:3 (add tid:3 as son of tid:3)

I'm thinking this might be a tad expensive query-wise if we don't do it correctly. Perhaps we might even come up with a novel solution to do it all just using Solr =)

I think I have some time thursday + friday for this, Ill look into it.

coupet’s picture

A paper describing Castanet, an algorithm for automatically generating hierarchical faceted metadata.

Automating Creation of Hierarchical Faceted Metadata Structures
http://biotext.berkeley.edu/papers/castanet.pdf

robertDouglass’s picture

I'm backing off my statement that this can still go into 6.1. I want to get that branch locked down without introducing more moving parts. Changing to 6.2.

coupet - the article was quite interesting, but not relevant to this issue.

As to comment #64, I also think approach #1 is correct. A child taxonomy link, at least in the context of http://drupal.org/files/issues/401234_60.png , should include filters for its visible parents.

robertDouglass’s picture

Version: 6.x-1.x-dev » 6.x-2.x-dev
janusman’s picture

Status: Needs work » Needs review
FileSize
16.33 KB

New patch built upon the previous one by @mkalkbrenner et al...

Overview:

  • Adds an option to each Filter by Taxonomy block in admin/build/block/configure/[module]/[delta] to show that vocabulary as hierarchical or as flat.
  • Shows thus-configured facets as hierarchical, both in the "Filter by.." block, and in the "Current search" block.
  • Allows the keyword search to be removed (taken from #473554: Add an "unclick" link to search facet block)

It also now fixes the problem seen in #60.

Code-wise:

  • it moves the "current search" block code from apachesolr_search_block() into its own function for legibility. This is basically the reason it includes the patch from #473554: Add an "unclick" link to search facet block since that other patch
  • it adds a new public function to Solr_Base_Query.php : remove_keys().

My feeling is that the code could still be optimized a bit, but it seems stable and handles entry to a deep-nested term correctly.

And... a question:

Is there a use case for admins wanting to show hierarchical facets as flat/unrelated?

My first impulse is that it would be very unlikely...

In fact I think *not* showing terms hierarchically (IMO) can introduce usability hurdles into a site. Because of this, I'm asking here (@robertDouglass??) to reconsider having this "fix" go into 1.x.

mkalkbrenner’s picture

I tested janusman's patch from #69 against 6.x-1.x-dev 2009-Jul-30 in our environments and it works.
But I adjusted the patch a little.

I removed again two obsolete lines of code I previously removed in my patches:

--- apachesolr_search.module	(revision 30471)
+++ apachesolr_search.module	(working copy)
@@ -562,78 +562,99 @@
         // Get information needed by the taxonomy blocks about limits.
         $initial_limits = variable_get('apachesolr_facet_query_initial_limits', array());
         $limit_default = variable_get('apachesolr_facet_query_initial_limit_default', 10);
+        $reflect_hierarchy = variable_get('apachesolr_facet_reflect_hierarchy', array());
 
         // Handle taxonomy vocabulary facets
         if ((strpos($delta, 'im_vid_') === 0) && module_exists('taxonomy')) {
 
           if (is_object($response->facet_counts->facet_fields->$delta)) {
-            $contains_active = FALSE;
-            $terms = array();

Like mentioned in comments #9 and #15 I found another line that might cause a fatal error if you change a taxonomy's hierarchy without updating the index:

+                  foreach ($parents as $term) {
+                    $count = 0;
+                    if (property_exists($response->facet_counts->facet_fields->$delta, $term->tid)) {
+                      $count = $response->facet_counts->facet_fields->$delta->{$term->tid};
+                    }

Attached you'll find janusman's patch from #69 with these two adjustments.

dakala’s picture

Can't get this patch to work. Anyone willing to share a working patched module, please? Kindly contact me directly if you wish to help. Thanks.

robertDouglass’s picture

Status: Needs review » Needs work

I think this issue might allow us to simplify the patch slightly? #545094: Method to set Keys on Query

+  $reflect_hierarchy = variable_get('apachesolr_facet_reflect_hierarchy', array());
+  $form['apachesolr_facet_reflect_hierarchy'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Links reflect hierarchy'),
+    '#description' => t('Facet will be sorted hierarchically if it bases on a hierarchical taxonomy vocabulary.'),
+    '#default_value' => !empty($reflect_hierarchy[$module][$delta]),
+  );

Is there any reason why we don't do this automatically for all hierarchical taxonomy vocabularies? This would certainly be more user friendly, IMO.

Please, no more _functions. "Private" functions need to be class based or they're not private.

+function _apachesolr_search_get_unclick_query_key($res, $val) {
+function _apachesolr_search_nested_facet_items($input, $parent = '', $level = 0) {

I think the doxygen standard that we use is to put the type and variable on one line and the short description on the next line.

 /**
+ * Creates a link to trigger a new solr search after removing at least one of previously
+ * selected search filters. Therefor you have to pass the filters' field names and values.
+ *
+ * @param $query object current apachesolr query
+ * @param $facet_text string
+ * @param $remove array array(array('#name' => 'field name', '#value' => 'field value'), array('#name' => 'field name', '#value' => 'field value'))
+ * @return string themed unclick link
+ */

Why is $query passed by reference?

+function apachesolr_search_get_unclick_link(&$query, $facet_text, $remove) {

Coding style $a . $b

+function _apachesolr_search_get_unclick_query_key($res, $val) {
+  return $res.$val['#name'].$val['#value'];
+}

Full doxygen comments please:

 /**
+ * Return nested array of nested facet values for use with theme_item_list()
+ */
+function _apachesolr_search_nested_facet_items($input, $parent = '', $level = 0) {

Also, it can read: "Return nested array of facet values" (redundant "nested")

Either give a type hint in the function signature or cast $input to an array so we never get warnings on the foreach.

 /**
+ * Return nested array of nested facet values for use with theme_item_list()
+ */
+function _apachesolr_search_nested_facet_items($input, $parent = '', $level = 0) {
+  if ($level == 0) {
+    ksort($input);
+  }
+  $result = array();
+  foreach ($input as $key => $item) {

Full doxygen comments please:

+/**
+ * Return the contents of the "Current search" block.
+ */
+function apachesolr_search_currentsearch_block($response, $query) {

Extra commented line?

+  #$links[] = apachesolr_l($query->get_query_basic(), $query->get_path(), array('attributes' => array('class' => 'active')));
janusman’s picture

Status: Needs work » Needs review
FileSize
15.42 KB

Implemented changes @robertDouglass mentioned in #72.

robertDouglass’s picture

Status: Needs review » Needs work

Patch doesn't apply to DRUPAL-6--2?

robertDouglass’s picture

patching file apachesolr_search.module
Hunk #2 FAILED at 653.
Hunk #3 succeeded at 784 (offset 5 lines).
Hunk #4 succeeded at 834 (offset 5 lines).
Hunk #5 succeeded at 1203 (offset 5 lines).

janusman’s picture

Status: Needs work » Needs review
FileSize
15.7 KB

!

Maybe 2.x changed before this patch =) Rerolled.

Forgot to mention that now there's no manual setting needed, the "show hierarchy" setting automatically applies to all vocabularies that are not freetagging nor multi-parent hierarchical (as determined by taxonomy_check_vocabulary_hierarchy()).

ruxkor’s picture

Has anybody tried to use this in combination with content taxonomy fields? I am currently having a hard time trying to implement a solution. :-/

robertDouglass’s picture

what exactly do you mean "content taxonomy fields"?

ruxkor’s picture

let me explain: by using the http://drupal.org/project/content_taxonomy content taxonomy module, it is possible to create cck fields using a taxonomy. the storage for those content taxonomy fields differs from the "normal" vocabularies if the setting "add to core taxonomy" is disabled (which is the case for many content taxonomy fields I am using for a project).

It is currently not possible to use those cck fields as a hierarchical facet since their string doesnt match to strpos($delta, 'im_vid_') === 0.

An apparently correct but at second thought wrong solution could be altering a document prior uploading it to solr by parsing all given cck fields, checking if they are from the type "taxonomy" and set the values in analogy to the core taxonomy fields (eg similar to apachesolr_add_taxonomy_to_document) BUT: That would eliminate the information about our cck field! Imagine two content taxonomy fields using the same vocabulary. By adding all content taxonomy fields to the tid, im_vid_# and vid values it would be still not possible to filter for a specific cck field, but only for a specific vocabulary.

The result is that content taxonomy fields need their own sets of multivalues, eg im_tid_MYCCKFIELD and im_vid_MYCCKFIELD_vid_# etc. But this means that almost the entire code has be adapted. :-/ After several hours of work I got some results but I am not really convinced by it; I used hooks whenever possible or added some new hooks and rebuilt a big part of this patch in my own search module (instead of directly adding things to the module) since patching would become even more terrible if I would directly modify the code :-(

Any ideas? Is there somebody else who ran into the same problem?

robertDouglass’s picture

ruxkor: One solution might be to write a module that provides facet blocks for content_taxonomy. The core apachesolr modules are unlikely to support this directly, and as you pointed out, the important bits are rather straightforward string comparisons. Please open a different issue as it's not actually directly related to this one. Thanks.

janusman’s picture

@ruxkor: I am currently using content_taxonomy fields in our production site; we *do* have "Additionally store in the core taxonomy system" option checked for all these fields so Apache Solr works out of the box with those fields.

If you want to go this way, then try looking at this issue: #485328: Provide a way to import and migrate from traditional taxonomy field ... we had to re-import our field values into the CCK tables during our migration to D6.

janusman’s picture

FileSize
15.49 KB

Patch didn't apply anymore, rolled a new one.

janusman’s picture

FileSize
15.48 KB

Patch failed to apply, bad line in Hunk #2... new patch.

Anonymous’s picture

I've tried the most recent patch #83 and it doesn't work. Any new patches available?

pwolanin’s picture

We should probably get this in 1.x first if we want to reach 1.0?

mkalkbrenner’s picture

"We should probably get this in 1.x first if we want to reach 1.0?"

I really appreciate that. Like I mentioned earlier (custom) forum searches without that feature simply make no sense. And this is a must have for a 1.0 release. We're running apachesolr 1.0-rc1 on three web sites now using the patches from #70 or #73 and everyone is happy with that.

janusman’s picture

This is frustrating; since the patch touches a lot of code and the module itself (the 2.x branch anyways) has been changing frequently, it has to be reviewed quickly or else it won't apply when a reviewer comes along. =)

Perhaps 6.x-1.x is a slower-moving target?

If I can get confirmation from someone willing to review this, I can re-roll the patch (just tell me which branch I should aim for!) =)

pwolanin’s picture

Version: 6.x-2.x-dev » 6.x-1.x-dev

I've been trying to find time to review - if you can re-roll for the 1.x branch then ping me about it.

We all agreed this would go in the 1.x branch, so let's try to get the code right there and then port it.

janusman’s picture

FileSize
16.17 KB

New patch, this is for 6.x-1.x-dev.

pwolanin’s picture

Status: Needs review » Needs work

looks like there are unrelated changes in the patch to Solr_Base_Query.php

janusman’s picture

Status: Needs work » Needs review
FileSize
14.83 KB

Correct. New patch.

pwolanin’s picture

Looks like this ought to be using constants defined by taxonomy module?

if ($voc->hierarchy != 2 && $voc->tags != 1) {
janusman’s picture

Uhm... there are no defined constants in the D6 core taxonomy module... same in D7 =)

To prove it, here's a bit of code inside taxonomy_help()... the rest of the code also compares tags and hierarchy to ">0", "==2", etc.:

    case 'admin/content/taxonomy/%':
      $vocabulary = taxonomy_vocabulary_load($arg[3]);
      if ($vocabulary->tags) {
        return '<p>'. t('%capital_name is a free-tagging vocabulary. To change the name or description of a term, click the <em>edit</em> link next to the term.', array('%capital_name' => drupal_ucfirst($vocabulary->name))) .'</p>';
      }
      switch ($vocabulary->hierarchy) {
        case 0:
          return '<p>'. t('%capital_name is a flat vocabulary. You may organize the terms in the %name vocabulary by using the handles on the left side of the table. To change the name or description of a term, click the <em>edit</em> link next to the term.', array('%capital_name' => drupal_ucfirst($vocabulary->name), '%name' => $vocabulary->name)) .'</p>';
        case 1:
          return '<p>'. t('%capital_name is a single hierarchy vocabulary. You may organize the terms in the %name vocabulary by using the handles on the left side of the table. To change the name or description of a term, click the <em>edit</em> link next to the term.', array('%capital_name' => drupal_ucfirst($vocabulary->name), '%name' => $vocabulary->name)) .'</p>';
        case 2:
          return '<p>'. t('%capital_name is a multiple hierarchy vocabulary. To change the name or description of a term, click the <em>edit</em> link next to the term. Drag and drop of multiple hierarchies is not supported, but you can re-enable drag and drop support by editing each term to include only a single parent.', array('%capital_name' => drupal_ucfirst($vocabulary->name))) .'</p>';
      }
pwolanin’s picture

Wow, taxonomy module sucks...

fabdel’s picture

Hi,

Suscribe for the hierachy of taxonomy in apachesolr.
Sorry but the hierarchy doesn't work.
I've always a flat taxonomy.
Drupal 6.14. I've apply the apachesolr-401234-91.patch.
Tested with apachesolr 6.1.x DEV and the the 6.x-1.0-rc3.

Really don't understand.

mkalkbrenner’s picture

@fabdel:
If you like, you can contact me to get an already patched version of 6.x-1.0-rc3.

pwolanin’s picture

Status: Needs review » Needs work

Trying out the last patch - I see the same issue as fabdel - the hierarchy doesn't show.

pwolanin’s picture

oh, wait - this is sort of working - but very counter-intuitive to me. The initial search result only shows the top level parent that's matched - no necessarily the actual term in the search results.

pwolanin’s picture

Patch needs work no matter what, since it will WSOD if taxonomy module is disabled:

 Fatal error: Call to undefined function taxonomy_get_vocabularies()
janusman’s picture

Wow.. this is comment #100...

IMO, we *want* to actually display just the top level terms, since there potentially could be too many child terms, they might never be shown. Also, it's in the spirit of "drilling down" to find what you need (which is what faceted search is good for... making large, complex data sets) =)

Say you have terms for the diferent animal kingdoms/Pylums/classes/etc inside a taxonomy. If you do a text search for "wings" it would get messy to display ALL the matching species's terms in an apachesolr block. What you want is to narrow down, starting from the top Phylum then drill down .. until you get to the insects or birds, etc.

This is the way a lot of faceted search interfaces work. If you're unconvinced I can look up a few cases.

I'll fix the patch to check for the taxonomy dependency found in #99.

mkalkbrenner’s picture

The usage of function taxonomy_get_vocabularies() was introduced with patch from comment #73.

Like in function apachesolr_search_apachesolr_facets() it should be wrapped by if (module_exists('taxonomy')) { ... } somehow.

But the problem is not only limited to this patch. Function _apachesolr_field_name_map($field_name) also calls function taxonomy_get_vocabularies() without any checks.

janusman’s picture

FileSize
13.92 KB

New patch, fixing the comment from #99 if taxonomy module was not enabled.

janusman’s picture

Status: Needs work » Needs review

Forgot to set as needs review.

pwolanin’s picture

regarding displaying the hierarchy - we currently display all the parents of any term on a node, so the number problem already exists.

Perhaps what's bothering me is the UI - in this case we kind of need something like the menu block have to indicate that a term has children.

Also, is it the right behavior to always reflec tthe hierarchy, or are there use cases where search results shoudl display a hierarchy flat as we have now?

mkalkbrenner’s picture

"Also, is it the right behavior to always reflect the hierarchy, or are there use cases where search results shoudl display a hierarchy flat as we have now?"

My original patch provided a check box on the settings form to switch between hierarchical and flat view per vocabulary. I think it was Robert's decision to remove that feature.

BTW if you want to see a live demo of this feature have a look at our public beta of http://www.coupons-proben.de/
The navigation on the left is nothing else than a facets. "Kategorien" are hierarchical.

pwolanin’s picture

Nice implementation - I like the check to X transition when you hover over the unclick link.

robertDouglass’s picture

Agree, nice hover effect =)

With regards to the handling of the block behavior, I'm still in favor of not making it configurable. I will cede the point if others feel strongly about it. There are already many ways (especially in 6.2) to configure blocks, with more on the way, and it is quickly becoming a nightmare to manage that form. That's my motivation for trying to make the apachesolr_search module make as many assumptions as we comfortably can.

mkalkbrenner’s picture

I once decided to offer a switch to turn the feature on and off to be backwards compatible and to increase the chances to get this patch accepted.
Nevertheless, as I mentioned earlier in this thread I'm of the opinion that a flat list isn't suitable to reflect a hierarchical vocabulary. So Robert's approach sounds good to me.
But if it's a blocker to get this feature into the final release o 6.x-1.0 I'm also fine with this configuration option.
Who's in charge to make a final decision?

robertDouglass’s picture

Ok. The switch is a non-issue. We leave it out.

robertDouglass’s picture

And, just because I'm busy right now and can't double check, please explain again how this degrades when no JS is enabled? Thanks.

pwolanin’s picture

I don't think we need a switch in the UI - it can be an opaque variable. I just would like to leave the options open.

robertDouglass’s picture

opaque variable ++
Those never hurt anything.

robertDouglass’s picture

Version: 6.x-1.x-dev » 6.x-2.x-dev

I still think we should not introduce this to 6.1 at this point in the game. Can we re-roll for 6.2? /me wants to see a 1.0 release for 6.1.

pwolanin’s picture

This has been on the roadmap for 6.x-1.0 for a while as the last major feature - just lack of time has prevented us from getting it in.

mkalkbrenner’s picture

In, out, in, out, ...
1.x, 2.x, 1.x, 2.x, ...

I remember an email thread with Peter in May after he posted comment #19. I asked him if I should go for a separate module for this feature.
The decision was to keep on going as a patch and I implemented everything he asked me for via mail or comments to this issue during the next weeks.

During this time apachsolr changed heavily and it wasn't easy to keep this patch in sync with the cvs. This caused me to post comment #61 in July.

Robert, do you remember your statement from comment #62?

At this point janusman offered his help and implemented Robert's and Peter's requests. But if I look at the comments he maybe ran into the same frustrating situation which stopped me contributing too much to this patch in August as you decided to schedule this feature for 2.x.

Than I was happy as I recognized comment #88 where Peter decided to get this feature back into 1.x.

Please don't get wrong. Apachesolr is still an awsome module and I'll keep contributing to it. But to keep your contributers motivated you maintainers have to make a final decision right now.

First option: keep this patch for 1.x and get our help to finalize it.

Second option: move this patch to 2.x and ask janusman to adjust it one more time to meet the current state of the cvs version. But than immediately commit it to cvs and fine tune it as a normal feature of apachesolr in the future.

The third option is a no go: move the patch to 2.x and ask somebody to keep it in sync with cvs until somebody else will commit it to cvs some day. That's what happend over the last half year.

If this feature doesn't make it into the final 1.0 release of apachesolr, everybody who's interested can download an alternative stable version at http://drupal.cocomore.com/de/project/apachesolr
As requested by our customers we'll provide and maintain this version until hierarchical facets and localization will be available in an official release of apachesolr at drupal.org.

Markus

pwolanin’s picture

Version: 6.x-2.x-dev » 6.x-1.x-dev

I'd been intending to find a couple hours and then get this in for 1.x.

janusman’s picture

@mkalkbrenner's post is an amplified mirror of my opinions =)

@pwolanin please if you need any help, clarification, b33r, etc. PM me.

pwolanin’s picture

Status: Needs review » Needs work

I'm working on rerolling it, but some serious problems with the last patch including apachesolr_search_currentsearch_block() is never called.

Also: Fatal error: Call to undefined method Solr_Base_Query::set_keys()

The last patch doesn't apply because it conflicts with Robert's last (little) commit.

pwolanin’s picture

FileSize
16.24 KB

Here's a patch that applies at least, and no fatal errors.

pwolanin’s picture

Status: Needs work » Needs review
FileSize
16.17 KB

Hmm, I am still dissatisfied that their is no prior indication which terms have child terms.

Slightly improved patch.

pwolanin’s picture

It seems like we could make the parent lookup much more efficient - use a single query instead of a query per term.

robertDouglass’s picture

@mkalkbrenner - I understand your frustration with a long-winded patch. I'm also not completely happy with adding new features to 1.0 when we should be trying to get a release out, but I find people's dedication to contributing more important, so if the interested parties here dearly want it in 1.0 then I won't stand in the way. It will need to get ported to 6.2 when finished.

janusman’s picture

Status: Needs review » Reviewed & tested by the community

Tested, works.

@pwolanin: re 120: Uhm, I don't think we're doing anything similar with the date facets, where it is also not clear that there is the option to further drill down by day, hour, etc. So I don't think the visual aspect for this is a blocking issue, but agreed, it's something that can be improved on across the whole module. Maybe we should think of rendering menu-like facet trees using menu_tree_output() using a faux-pas tree? Or just use core's classes for menu items... I suggest we open a new issue for this.

re 121: I will do some benchmarks to see which is better performance-wise. I don't think it's a blocking issue either.

pwolanin’s picture

Status: Reviewed & tested by the community » Needs work

I'm not happy yet with the architecture of the code, even though it works.

There is some kind of funny string parsing going on to keep track of the depth of each item.

janusman’s picture

Assigned: janusman » Unassigned

Hmm, it's funny that you set the patch to needing review when you already knew the outcome... maybe you didn't mean to?

The string parsing going on is just a way to define (via the key) the number of terms, the term id, and the parent-child relationship in a way that can IMO be parsed simply (with little code) and quickly. Maybe you want a data structure of nested arrays or objects?

Please indicate if you need comments sprinkled/doused on the code... or any other specific help on this (please be specific). It's not worth putting any more time into this if it'll still get bounced due to Mysterious Reason N+1 =)

Removing myself from "Assigned:"

pwolanin’s picture

I'm only putting to CNW because I was planning to work on the code a little more myself.

janusman’s picture

Apologies, I assumed the CNW was meant for me because I was still assigned to the issue. =)

pwolanin’s picture

no, sorry - I generally don't pay much attention to the assigned flag once I start looking at a patch :-)

pwolanin’s picture

This isn't working yet, but partially re-written.

Could substantially reduce the # of queries, but is possibly a little less robust to there being stale data in the index.

pwolanin’s picture

The code in the current search block potentially generates the same unclick link multiple times. I think this line in the new function apachesolr_search_currentsearch_block() will be called 2x for the same key if a parent and child term are both in the current search block:

$active_facets_unclick[$facet_fieldname][$key] = apachesolr_search_get_unclick_link($query, $fielddisplay, $remove);
pwolanin’s picture

Status: Needs work » Needs review
FileSize
14.52 KB

Here is a massively revised patch.

Please review to see if you follow the logic of the code - it uses variable references in a way that's hopefully transparent enough to understand.

The code added here will can be used to render any properly constructed hierarchical facets.

There is a slight amount of work to be done yet in terms of perfecting the classes for items that have children but are collapsed, versus having children and open.

pwolanin’s picture

FileSize
15.1 KB

some minor cleanup.

robertDouglass’s picture

This is going to be fun to forward port :\

The thing the jumps out at me as being ugly is how we get facet texts. Horrible. But that's a separate issue.

I'll test in the coming days. Looking for feedback from janusman and mkalkbrenner as well.

pwolanin’s picture

FileSize
15.9 KB

oops - that last patch missed the minor change to the query class.

Hopefully should not be too hard to port - basically jsut moves all the currentsearch and taxononmy facet code out of the big hook_block into separate functions,

janusman’s picture

Haven't tested it yet, just reviewing the code...

+++ apachesolr_search.module	29 Nov 2009 14:01:30 -0000
@@ -690,6 +624,90 @@ function apachesolr_search_block($op = '
+          // We don't display children unless the parent is clicked.
+          if (!$query->has_filter('tid', $term->parent)) {
+            unset($facets[$term->tid]);
+          }
+          else {
+            $facets[$term->tid]['#parent'] = $term->parent;
+            // Use a reference so we see the updated data.
+            $facets[$term->parent]['#children'][] = &$facets[$term->tid];
+          }

I think the above could cause a problem if the user enters a search from the taxonomy pages override (e.g. going to /taxonomy/term/xxx). Will test...

And, in apachesolr_search_currentsearch_block()... am I misreading, or are we only handling keys and taxonomy terms in the current search block? (No dates, authors, etc?)

pwolanin’s picture

The current search block special-cases keys and taxonomy, but all others should still work.

janusman’s picture

FileSize
59.97 KB
10.56 KB

Ok here's what I've found:

1) My observation from #135 is true: I have this taxonomy:

  • Engineering & Applied Science (taxonomy/term/62547)
    • Applied Physics (taxonomy/term/62712)

If I have "Use ApacheSolr as the default for taxonomy term pages", and I go to an inner term (say, "Applied Physics" from above), then the current search and the facet block for that taxonomy are confusing:

  • Current search block: only shows "Applied Physics", as an active filter.
  • Hierarchical facet term block: only shows the parent "Engineering & Applied Science", inactive.

401234-137-1.jpg

2) Something definitely broken with the nesting:

401234-137-2.jpg

3) The expand/contract class handling is awesome! =) Just that you're adding a class called "expanded-facet", maybe you meant "expanded"? If you did mean to add in a new class, would there be any harm in also adding the "expanded" class?

+++ apachesolr_search.module 29 Nov 2009 14:01:30 -0000
@@ -703,6 +721,62 @@ function apachesolr_search_get_book($fac
+      $link['class'] = "expanded-facet";
janusman’s picture

A possible clue to #137 (2):

I think somehow the algorithm is missing every even-level item. In the above screenshot it missed showing and "Business" (2nd level), "Finance (General)" (4th level).

*EDIT* I meant they are just "missing" in the rendered facet block; they are indeed indexed properly.

janusman’s picture

FileSize
15.41 KB

This patch fixes issue 2 from #137.

janusman’s picture

FileSize
15.72 KB
92.46 KB

Another issue: the "collapsed" class on list items depends on the returned facet values but should instead depend on the database. This is because the Solr facet list could get cut off just enough in some cases to not show properly:
401234-140.jpg

The attached patch fixes this issue, here is a diff between the patch in #139 and this one.

@@ -185,7 +185,7 @@
+    }
+
+    if ($facets && $reflect_hierarchy[$vocab->vid]) {
-+      $result = db_query("SELECT tid, parent FROM {term_hierarchy} WHERE tid IN (". db_placeholders($facets) .")", array_keys($facets));
++      $result = db_query("SELECT TH.tid, TH.parent, SUM(IF(ISNULL(TH2.tid),0,1)) AS has_children FROM {term_hierarchy} TH LEFT JOIN {term_hierarchy} TH2 ON TH2.parent = TH.tid AND TH2.parent IN (". db_placeholders($facets) .") WHERE TH.tid IN (". db_placeholders($facets) .") GROUP BY TH.tid", array_merge(array_keys($facets), array_keys($facets)));
+      while ($term = db_fetch_object($result)) {
+        // Mark all terms that are parents for later CSS class.
+        if (isset($facets[$term->parent])) {
@@ -194,6 +194,9 @@
+          // Use a reference so we see the updated data.
+          $facets[$term->parent]['#children'][] = &$facets[$term->tid];
+        }
++        if ($term->has_children > 0) {
++          $facets[$term->tid]['#has_children'] = TRUE;
++        }
+      }
+      foreach ($facets as $tid => $field) {
+        if (!empty($field['#parent'])) {
pwolanin’s picture

Given that we expect relatively few (~20 ?) items per block response, can't we convert the query to an OR query rather than doing the join back as you have?

i.e. something like:

 $result = db_query("SELECT tid, parent FROM {term_hierarchy} WHERE tid IN (". db_placeholders($facets) .") OR parent IN (". db_placeholders($facets) .")", array_keys($facets), array_keys($facets));
janusman’s picture

I'd side with the best-performing query =)

pwolanin’s picture

FileSize
16.05 KB

ok, well I don't have a good data set to bench mark, but we might (or might not) make the code faster by also adding the condition parent > 0, which is really what we want.

Here's a patch - can you try?

It's also possible that 2 queries will be faster?

janusman’s picture

Your query performs better.

You only missed a spot:

+++ apachesolr_search.module	1 Dec 2009 01:33:37 -0000
@@ -690,6 +624,88 @@ function apachesolr_search_block($op = '
+      $result = db_query("SELECT tid, parent FROM {term_hierarchy} WHERE parent > 0 AND (tid IN ($placeholders) OR parent IN ($placeholders))", $tids, $tids);

"$tids, $tids" should become "array_merge($tids, $tids)" :

+++ apachesolr_search.module	1 Dec 2009 01:33:37 -0000
@@ -690,6 +624,88 @@ function apachesolr_search_block($op = '
+      $result = db_query("SELECT tid, parent FROM {term_hierarchy} WHERE parent > 0 AND (tid IN ($placeholders) OR parent IN ($placeholders))", array_merge($tids, $tids));

So this fixes issue (2) from #137.

The only thing left I see is issue (1) from #137: starting out in a child term search, from either a taxonom/term/XXX page override, or search/apachesolr_search/?filters=tid:XXXX, shows confusing links. (See the description and screenshot in #137)

pwolanin’s picture

FileSize
16.09 KB

oh right - here's a fixed patch with the array_merge.

janusman’s picture

FileSize
123.14 KB

The only thing left I see is issue (1) from #137: starting out in a child term search, from either a taxonom/term/XXX page override, or search/apachesolr_search/?filters=tid:XXXX, shows confusing links. (See the description and screenshot in #137)

I see it as a problem; anyone have an opinion on it? =)

401234-146.png

pwolanin’s picture

This seems like a separate bug - why is this tid not in the list of active filters in the query object?

pwolanin’s picture

Ah, maybe this is a bug - the previous code was finding all parents. Too. The facet that the facet block is not correct confuses me.

pwolanin’s picture

Hmm, there are possibly sql rewite issues we need to ponder as well.

janusman’s picture

The problem from #146 is this:

Going directly to a "deep" term for an URL like search/apachesolr_search?filters=tid:2 or taxonomy/term/2 causes the problem because the parent (or parent's parent, or...) is NOT in the URL and the code just getting the inmediate parent (not the parent's parent, etc).

Before we embark on any fix, my question is: is this a problem related to this issue, or a different issue altogether?

I'm thinking this is a different issue, introduced by #472600: Replace taxonomy/term/XXX node listings with Apache Solr search results. Thoughts?

pwolanin’s picture

FileSize
17.9 KB

Maybe some way to strip this code down further? Feels like a lot of bloat to load on every page.

I think it at least addresses the bug raised in the last screen shot.

pwolanin’s picture

FileSize
17.93 KB

Slight tweak

janusman’s picture

Status: Needs review » Reviewed & tested by the community

Awesome.

Tested, fixes the problems I mentioned... I think this is RTBC.

pwolanin’s picture

I think I may still have sen some bug where the child of an active link was not shown, but in general it seems to work right.

Let's get this in - then maybe we can think about some unit or system tests even to look for broken behavior.

committing to 6.x-1.x.

@janusman - do you have a reasonable sized text vocabulary we could use? Or a sampling of it?

pwolanin’s picture

Version: 6.x-1.x-dev » 6.x-2.x-dev
Status: Reviewed & tested by the community » Patch (to be ported)
janusman’s picture

re #154: Yes I do have a large hierarchical vocabulary; to get it install this module:

http://drupal.org/project/hilcc

which will create a new taxonomy with some 1,000 terms... when enabling it will show a message pointing to the newly-created vocabulary.

robertDouglass’s picture

FileSize
21.05 KB

The hierarchy and the check boxes don't work well together. One possible solution is to try to clean it up with CSS. Another possible solution is to not to checkboxes on expandable items. Thoughts?

robertDouglass’s picture

Status: Patch (to be ported) » Needs work
FileSize
18.96 KB

Committing this patch as a stop gap to stay in sync with 6.1

rjbrown99’s picture

Hi. I just spent the past hour or two trying to figure out why my taxonomy facet block, which is for a hierarchical multi-parent taxonomy, was not displayed that way. Here's why. I'm using 6.x-2.0-alpha1.

In apachesolr_search_module, inside of the function apachesolr_search_get_hierarchical_vocabularies(), the following statement exists:

      foreach ($vocabularies as $voc) {
        // If the vocabulary is not multiple-parent hierarchical and not
        // freetagging and not designated to be forced to display flat.
        if ($voc->hierarchy != 2 && $voc->tags != 1 && empty($force_flat[$voc->vid])) {
          $result[$voc->vid] = 1;
        }
      }

In my case, my vocabulary is a multi-parent taxonomy and it is hierarchical. The first part of this if statement fails because $voc->hierarchy equals 2. The result never gets set to 1, and my block displays the content in a flat list.

I read post #76 above and this seems to be intentional. Question: why do we disable hierarchy for multi-parent taxonomies? Would this break if I modified that if statement to display them?

Thanks.

claudiu.cristea’s picture

Committed to DRUPAL-5--2, in #318058.

Patch attached.

claudiu.cristea’s picture

After appying the patch from #160 I notice that the filters text for CCK filters, from Current Search block are disappearing.

This because the facet text is build in apachesolr_search_nested_facet_items() in the line:

    $facet_text = theme('apachesolr_breadcrumb_' . $field['#name'], $field, $field['#exclude']);

But when a CCK field is passed, the theme invoked is not correct... For example, for a CCK field called "field_city" the value $field['#name'] = 'is_cck_field_city' (the Solr mapping) and the invoked theme will be theme('apachesolr_breadcrumb_is_cck_field_city') which does not exists.

claudiu.cristea’s picture

Priority: Normal » Critical
Aldus’s picture

would it be possible to have a different facet for each taxonomy level?

jpmckinney’s picture

Version: 6.x-2.x-dev » 5.x-2.x-dev
Category: feature » bug

The patch has already been ported to 2.x.

The bug in #161 is critical for 5.x-2.x, so that's what this issue will be about. Replying to some other comments:

@Aldus #163: Please create a new issue for discussing having a different facet/facet block for each taxonomy level.

@rjbrown99 #159: Please create a new issue for discussing multi-parent hierarchical taxonomy facets.

@robertDouglass #157: Create a UI issue with a patch.

jpmckinney’s picture

Status: Needs work » Fixed

The bug in #161 was fixed in #724440: Current search does not display properly the CCK filters. RE: #157, #159, #163: create new issues.

This was the last bug in 5.x-2.x. Yay!

Status: Fixed » Closed (fixed)

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

CosticaPuntaru’s picture

Version: 5.x-2.x-dev » 7.x-1.4

its this patch applied on d7 versions?
i can see a Expand hierarchy checkbox option, but it dosen't seem to have any effects(or it has some sort of bug on my websites)

russellb’s picture

I'd also be interested to know if people are using hierarchical taxonomies for Solr facets in D7.

8bitplateau’s picture

Issue summary: View changes

The Facets are not supplied by this module any more, the are from FacetAPI.
I think this may help you : https://www.drupal.org/project/apachesolr/issues/2954804#comment-12549596