Skip to content
Snippets Groups Projects
Commit 41db58c7 authored by Ere Maijala's avatar Ere Maijala Committed by Demian Katz
Browse files

Added support for "exact" searches

- Exact search = search terms in quotes using different search specs.
parent ec459298
Branches
Tags
No related merge requests found
...@@ -51,6 +51,12 @@ ...@@ -51,6 +51,12 @@
# # for an example. This is applied whether we use DismaxFields or # # for an example. This is applied whether we use DismaxFields or
# # QueryFields. # # QueryFields.
# FilterQuery: (optional Lucene filter query) # FilterQuery: (optional Lucene filter query)
# ExactSettings:
# DismaxFields: ...
# QueryFields: ...
# # All the same settings as above, but for exact searches, i.e. search terms
# # enclosed in quotes. Allows different fields or weights for exact
# # searches. See below for commented-out examples.
# #
# ...etc. # ...etc.
# #
...@@ -208,6 +214,14 @@ Subject: ...@@ -208,6 +214,14 @@ Subject:
era: era:
- [and, 100] - [and, 100]
- [or, ~] - [or, ~]
# ExactSettings:
# DismaxFields:
# - topic_unstemmed^150
# QueryFields:
# - topic_unstemmed:
# - [onephrase, 350]
# - [and, 150]
# - [or, ~]
# This field definition is a compromise that supports both journal-level and # This field definition is a compromise that supports both journal-level and
# article-level data. The disadvantage is that hits in article titles will # article-level data. The disadvantage is that hits in article titles will
...@@ -253,6 +267,14 @@ JournalTitle: ...@@ -253,6 +267,14 @@ JournalTitle:
- [onephrase, 50] - [onephrase, 50]
- [and , ~] - [and , ~]
FilterQuery: "format:Journal OR format:Article" FilterQuery: "format:Journal OR format:Article"
# ExactSettings:
# DismaxFields:
# - title_full_unstemmed^450
# QueryFields:
# - title_full_unstemmed:
# - [onephrase, 450]
# - [and, 400]
# FilterQuery: "format:Journal OR format:Article"
Title: Title:
DismaxFields: DismaxFields:
...@@ -288,6 +310,13 @@ Title: ...@@ -288,6 +310,13 @@ Title:
series2: series2:
- [onephrase, 50] - [onephrase, 50]
- [and , ~] - [and , ~]
# ExactSettings:
# DismaxFields:
# - title_full_unstemmed^450
# QueryFields:
# - title_full_unstemmed:
# - [onephrase, 450]
# - [and, 400]
Series: Series:
DismaxFields: DismaxFields:
...@@ -382,6 +411,29 @@ AllFields: ...@@ -382,6 +411,29 @@ AllFields:
- [onephrase, ~] - [onephrase, ~]
issn: issn:
- [onephrase, ~] - [onephrase, ~]
# ExactSettings:
# DismaxFields:
# - title_full_unstemmed^600
# - topic_unstemmed^550
# - allfields_unstemmed^10
# - fulltext_unstemmed^10
# - isbn
# - issn
# QueryFields:
# title_full_unstemmed:
# - [onephrase, 600]
# - [and, 500]
# topic_unstemmed:
# - [onephrase, 550]
# - [and, 500]
# allfields_unstemmed:
# - [or, 10]
# fulltext_unstemmed:
# - [or, 10]
# isbn:
# - [onephrase, ~]
# issn:
# - [onephrase, ~]
# These are advanced searches that never use Dismax: # These are advanced searches that never use Dismax:
id: id:
......
...@@ -61,7 +61,14 @@ class QueryBuilder implements QueryBuilderInterface ...@@ -61,7 +61,14 @@ class QueryBuilder implements QueryBuilderInterface
* *
* @var array * @var array
*/ */
protected $specs; protected $specs = array();
/**
* Search specs for exact searches.
*
* @var array
*/
protected $exactSpecs = array();
/** /**
* Should we create the hl.q parameter when appropriate? * Should we create the hl.q parameter when appropriate?
...@@ -128,7 +135,7 @@ class QueryBuilder implements QueryBuilderInterface ...@@ -128,7 +135,7 @@ class QueryBuilder implements QueryBuilderInterface
} }
$string = $query->getString() ?: '*:*'; $string = $query->getString() ?: '*:*';
$handler = $this->getSearchHandler($query->getHandler()); $handler = $this->getSearchHandler($query->getHandler(), $string);
if (!($handler && $handler->hasExtendedDismax()) if (!($handler && $handler->hasExtendedDismax())
&& $this->getLuceneHelper()->containsAdvancedLuceneSyntax($string) && $this->getLuceneHelper()->containsAdvancedLuceneSyntax($string)
...@@ -204,6 +211,12 @@ class QueryBuilder implements QueryBuilderInterface ...@@ -204,6 +211,12 @@ class QueryBuilder implements QueryBuilderInterface
public function setSpecs(array $specs) public function setSpecs(array $specs)
{ {
foreach ($specs as $handler => $spec) { foreach ($specs as $handler => $spec) {
if (isset($spec['ExactSettings'])) {
$this->exactSpecs[strtolower($handler)] = new SearchHandler(
$spec['ExactSettings'], $this->defaultDismaxHandler
);
unset($spec['ExactSettings']);
}
$this->specs[strtolower($handler)] $this->specs[strtolower($handler)]
= new SearchHandler($spec, $this->defaultDismaxHandler); = new SearchHandler($spec, $this->defaultDismaxHandler);
} }
...@@ -239,18 +252,32 @@ class QueryBuilder implements QueryBuilderInterface ...@@ -239,18 +252,32 @@ class QueryBuilder implements QueryBuilderInterface
/** /**
* Return named search handler. * Return named search handler.
* *
* @param string $handler Search handler name * @param string $handler Search handler name
* @param string $searchString Search query
* *
* @return SearchHandler|null * @return SearchHandler|null
*/ */
protected function getSearchHandler($handler) protected function getSearchHandler($handler, $searchString)
{ {
$handler = $handler ? strtolower($handler) : $handler; $handler = $handler ? strtolower($handler) : $handler;
if ($handler && isset($this->specs[$handler])) { if ($handler) {
return $this->specs[$handler]; // Since we will rarely have exactSpecs set, it is less expensive
} else { // to check for a handler first before doing multiple string
return null; // operations to determine eligibility for exact handling.
if (isset($this->exactSpecs[$handler])) {
$searchString = isset($searchString) ? trim($searchString) : '';
if (strlen($searchString) > 1
&& substr($searchString, 0, 1) == '"'
&& substr($searchString, -1, 1) == '"'
) {
return $this->exactSpecs[$handler];
}
}
if (isset($this->specs[$handler])) {
return $this->specs[$handler];
}
} }
return null;
} }
/** /**
...@@ -292,7 +319,10 @@ class QueryBuilder implements QueryBuilderInterface ...@@ -292,7 +319,10 @@ class QueryBuilder implements QueryBuilderInterface
} else { } else {
$searchString = $this->getLuceneHelper() $searchString = $this->getLuceneHelper()
->normalizeSearchString($component->getString()); ->normalizeSearchString($component->getString());
$searchHandler = $this->getSearchHandler($component->getHandler()); $searchHandler = $this->getSearchHandler(
$component->getHandler(),
$searchString
);
if ($searchHandler) { if ($searchHandler) {
$searchString $searchString
= $this->createSearchString($searchString, $searchHandler); = $this->createSearchString($searchString, $searchHandler);
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment