facetapi_luceneapi.adapter.inc in Facet API 6
Classes used by the Facet API module.
File
contrib/facetapi_luceneapi/facetapi_luceneapi.adapter.incView source
<?php
/**
* @file
* Classes used by the Facet API module.
*/
/**
* Facet API adapter for Search Lucene API modules.
*/
class FacetapiLuceneapiAdapter extends FacetapiAdapter {
/**
* Returns a boolean flagging whether $this->_searcher executed a search.
*/
public function searchExecuted() {
return luceneapi_search_executed() == $this->_searcher;
}
/**
* The default method used to retrieve facet data.
*/
public function fetchTerm(array $facet) {
$facet_items = array();
$sql = "\n SELECT term\n FROM {" . $this
->getSearcher() . "_termfreqs}\n WHERE field = '%s'\n ";
// Gets the cached term frequencies.
if ($result = db_query($sql, array(
$facet['field'],
))) {
while ($record = db_fetch_object($result)) {
$term = new Zend_Search_Lucene_Index_Term($record->term, $facet['field']);
if ($count = facetapi_luceneapi_terms_count($this->_index, $this->_docs, array(
$term,
))) {
$facet_items[$record->term] = array(
'count' => $count,
);
}
}
}
return $facet_items;
}
/**
* Fetches data from facets that filter results by date ranges.
*/
public function fetchDate(array $facet) {
$sql = "\n SELECT MIN(term) as minimum, MAX(term) as maximum\n FROM {" . $this
->getSearcher() . "_termfreqs}\n WHERE field = '%s'\n ";
// Calculates the minimum and maximum values.
$range = array();
if ($result = db_query($sql, array(
$facet['field'],
))) {
if ($record = db_fetch_object($result)) {
$range = array(
$record->minimum,
$record->maximum,
);
}
}
// Gets all values in the resultset.
$raw_values = array();
foreach (facetapi_luceneapi_range_matches_get($this->_index, $range[0], $range[1], TRUE, array(
$facet['field'],
)) as $key => $term) {
if ($count = facetapi_luceneapi_terms_count($this->_index, $this->_docs, array(
$term,
))) {
$raw_values[$term->text] = $count;
}
}
// Sorts by timestamp if there are values, otherwise return an empty array.
if (!empty($raw_values)) {
$facet_items = array();
ksort($raw_values);
}
else {
return array();
}
// Gets the active date facets, starts to builds the "parent - child"
// relationships.
$parent = NULL;
$gap = NULL;
foreach ($this
->getActiveFacets($facet['field alias']) as $value => $active_facet) {
// Strips field from value, adds to $facet_items array.
$facet_items[$value] = array(
'count' => count($this->_docs),
);
// Gets next "gap" increment, mintue being the lowest be can go.
$gap = facetapi_next_date_gap_get(facetapi_date_gap_get($active_facet['start'], $active_facet['end']), FACETAPI_DATE_MINUTE);
// If there is a previous item, there is a parent, uses a reference so the
// arrays are populated when they are updated.
if (NULL !== $parent) {
$facet_items[$parent]['children'][$value] =& $facet_items[$value];
$facet_items[$value]['parents'][$parent] = $parent;
}
// Stores the last value iterated over.
$parent = $value;
}
// Mind the gap! Calculates gap from min and max timestamps.
$timestamps = array_keys($raw_values);
if (NULL === $parent) {
if (count($raw_values) > 1) {
$gap = facetapi_timestamp_gap_get(min($timestamps), max($timestamps));
}
else {
$gap = FACETAPI_DATE_HOUR;
}
}
// Converts all timestamps to dates in ISO 8601 format.
$dates = array_combine($timestamps, $timestamps);
array_walk($dates, 'facetapi_luceneapi_timestamp_convert', $gap);
// Treat each date as the range start and next data as the range end.
$range_end = array();
$previous = NULL;
foreach (array_unique($dates) as $date) {
if (NULL !== $previous) {
$range_end[$previous] = facetapi_next_date_increment_get($previous, $gap);
}
$previous = $date;
}
$range_end[$previous] = facetapi_next_date_increment_get($previous, $gap);
// Groups dates by the range they belong to, builds the $facet_items array
// with the facet counts and formatted range values.
foreach ($raw_values as $value => $count) {
$new_value = '[' . $dates[$value] . ' TO ' . $range_end[$dates[$value]] . ']';
if (!isset($facet_items[$new_value])) {
$facet_items[$new_value] = array(
'count' => $count,
);
}
else {
$facet_items[$new_value]['count'] += $count;
}
// Adds parent information if not already set.
if (NULL !== $parent && !isset($facet_items[$new_value]['parents'])) {
$facet_items[$parent]['children'][$new_value] =& $facet_items[$new_value];
$facet_items[$new_value]['parents'][$parent] = $parent;
}
}
// Returns the dates.
return $facet_items;
}
/**
* Overrides the fetch() function, prepopulates the termFreqs cache by calling
* the facetapi_luceneapi_termfreqs_get() function.
*/
public function fetch(array $facet) {
$term = new Zend_Search_Lucene_Index_Term(NULL, $facet['field']);
facetapi_luceneapi_termfreqs_get($this
->getSearcher(), $term);
return parent::fetch($facet);
}
/**
* Returns a normalized array with facet counts included.
*/
public function getFacetData(array $facet) {
// Opens the index, returns an empty index in it cannot be opened.
if (!($this->_index = luceneapi_index_open($this
->getSearcher(), $errstr))) {
luceneapi_throw_error($errstr);
return array();
}
// Ugly. We have to re-build the query.
// @todo Add an API function similar to apachesolr_current_query().
// Gets query container, appends user query and facet queries.
if (!($query = luceneapi_query_get('boolean'))) {
throw new LuceneAPI_Exception(t('Error instantiating boolean query.'));
}
// Parses user query if a string was passed.
$user_query = luceneapi_query_parse(search_get_keys(), $this
->getSearcher(), 'keys');
if (!$user_query || form_get_errors()) {
return array();
}
// Adds user query to query container, allows modules to alter the query.
luceneapi_subquery_add($query, $user_query, 'required', TRUE);
module_invoke_all('luceneapi_query_alter', $query, $this
->getSearcher(), $this
->getType());
// Gets documents matched in the query.
$this->_docs = facetapi_luceneapi_match_query($this->_index, $query);
return parent::getFacetData($realm_name, $facets);
}
/**
* Returns the search keys.
*/
public function getSearchKeys() {
if (NULL === $this->_keys) {
return search_get_keys();
}
return $this->_keys;
}
}
Classes
Name | Description |
---|---|
FacetapiLuceneapiAdapter | Facet API adapter for Search Lucene API modules. |