Forum

Notifications
Clear all

Advanced Search: filtering classifications as OR not AND

Elle
 Elle
(@jenny)
Honorable Member

So -- presently, the Advanced Search searches multiple classifications with AND. I'm looking into modifying the code so it will search via OR.

The suggestion on our archive explains it much more clearly:

In the "Advanced Search," I'd like to be able to have an "OR" capability in more fields than the "rating." ie, maybe I'm looking for a fic that is either year 7 OR year 8. Currently, I think "year" and "character" are only "AND" while "rating," I guess by virtue of it being discrete sets, is "OR". I haven't gone to test the others, but I'm pretty sure anything where the sets are not discrete would be "and".

As the classifications in the database are comma-separated values -- does anyone know if this is possible?

And if it's not... do you think it's possible advantageous to convert the current classifications-in-DB to a more DB-friendly way?

(e.g.
classifications: a table full of the classifications
classification_types: a table full of the classification types
classification_story: table joining classification IDs and classification story IDs)

I haven't ventured into the inner workings of my eFiction archive for a long, long time and my MySQL knowledge is really rusty! Any help/discussion would be appreciated.

archive: dramione.org
site: accio.nu

Available for skin/mod commission! 🙂

Quote
Topic starter Posted : 23/06/2013 4:34 am
SJP
 SJP
(@sjp)
Trusted Member

Okay, so I'm no expert, so take this with a grain of salt 🙂 . However, I decided to mess with this and see what I could come up with.

It looks like category options and ratings are already OR instead of AND. That leaves characters and classifications.

Changing character search is the easy part. Around line 156, you'll see:

		if(count($charstories) > 0) {
$query[] = "(".implode(" AND ", $charstories).")";
$countquery[] = "(".implode(" AND ", $charstories).")";
}
if(count($charseries) > 0) $scountquery[] = "(".implode(" AND ", $charseries).")";
}

Change that to:

              if(count($charstories) > 0) {
$query[] = "(".implode(" OR ", $charstories).")";
$countquery[] = "(".implode(" OR ", $charstories).")";
}
if(count($charseries) > 0) $scountquery[] = "(".implode(" OR ", $charseries).")";
}

to switch the classifications to an OR search, there's a bit more to add. The classification section starting around line 194 is as follows:

      if($classin) {
foreach($classin as $class) {
$query[] = "FIND_IN_SET($class, stories.classes) > 0";
$countquery[] = "FIND_IN_SET($class, stories.classes) > 0";
$scountquery[] = "FIND_IN_SET($class, series.classes) > 0";
}
}
if($classex) {
foreach($classex as $class) {
$query[] = "FIND_IN_SET($class, stories.classes) = 0";
$countquery[] = "FIND_IN_SET($class, stories.classes) = 0";
$scountquery[] = "FIND_IN_SET($class, series.classes) = 0";
}
}

It needs to be changed to:

    		if($classin) {
foreach($classin as $class) {
$classstories[] = "FIND_IN_SET($class, stories.classes) > 0";
$classstories[] = "FIND_IN_SET($class, stories.classes) > 0";
$classseries[] = "FIND_IN_SET($class, series.classes) > 0";
}
if(!empty($classstories)) {
$query[] = "(".implode(" OR ", $classstories).")";
$countquery[] = "(".implode(" OR ", $classstories).")";
$scountquery[] = "(".implode(" OR ", $classseries).")";
}
}
if($classex) {
foreach($classex as $class) {
$query[] = "FIND_IN_SET($class, stories.classes) = 0";
$countquery[] = "FIND_IN_SET($class, stories.classes) = 0";
$scountquery[] = "FIND_IN_SET($class, series.classes) = 0";
}
}

I got this working properly on my test site, so give it a try and see if it helps. Good luck.

ReplyQuote
Posted : 24/06/2013 5:19 am
Elle
 Elle
(@jenny)
Honorable Member

Thanks, SJP! I have implemented it and, so far, no complaints, so I think it's worked. 😛

archive: dramione.org
site: accio.nu

Available for skin/mod commission! 🙂

ReplyQuote
Topic starter Posted : 26/06/2013 6:36 pm
Share: