-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathsearch_api_solr_datasource.module
133 lines (118 loc) · 4.97 KB
/
search_api_solr_datasource.module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?php
/**
* @file
* Contains hook functions for the Search API Solr Datasource module.
*/
use Drupal\search_api\IndexInterface;
use Drupal\search_api\Query\QueryInterface;
use Drupal\search_api\Query\ResultSetInterface;
use Solarium\QueryType\Select\Query\Query as SolariumQuery;
use Solarium\QueryType\Select\Result\Result as SolariumResult;
/**
* Implements hook_search_api_field_type_mapping_alter().
*
* Add mappings for Solr data types to Search API data types.
*/
function search_api_solr_datasource_search_api_field_type_mapping_alter(array &$mapping) {
$mapping['long'] = 'integer';
$mapping['tdate'] = 'date';
$mapping['text'] = 'text';
}
/**
* Implements hook_search_api_solr_field_mapping_alter().
*
* Override the default fields that Search API Solr sets up. In particular,
* set the ID field to the one that is configured via the datasource config
* form.
*
* Also, map the index's field names to the original property paths. Search API
* Solr adds prefixes to the paths because it assumes that it has done the
* indexing according to its schema.xml rules. Of course, in our case it hasn't
* and we need it to use the raw paths. Any field machine names that have been
* altered in the field list will have their mapping corrected by this step too.
*
* @see \Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend::getSolrFieldNames()
*/
function search_api_solr_datasource_search_api_solr_field_mapping_alter(IndexInterface $index, array &$fields) {
// Do not alter mappings if the index does not use the solr_document
// datasource.
$datasources = $index->getDatasources();
if (!isset($datasources['solr_document'])) {
return;
}
// Set the ID field.
$config = $index->getDatasource('solr_document')->getConfiguration();
$fields['search_api_id'] = $config['id_field'];
/** @var \Drupal\search_api\Item\FieldInterface[] $index_fields */
$index_fields = $index->getFields();
// Re-map the indexed fields.
foreach ($fields as $raw => $name) {
// Ignore the Search API fields.
if (strpos($raw, 'search_api_') === 0) {
continue;
}
$fields[$raw] = $index_fields[$raw]->getPropertyPath();
}
}
/**
* Implements hook_search_api_solr_query_alter().
*/
function search_api_solr_datasource_search_api_solr_query_alter(SolariumQuery $solarium_query, QueryInterface $query) {
// Do not alter the query if the index does not use the solr_document
// datasource.
$datasources = $query->getIndex()->getDatasources();
if (!isset($datasources['solr_document'])) {
return;
}
// Remove the filter queries that limit the results based on site and index.
$solarium_query->removeFilterQuery('site_hash');
$solarium_query->removeFilterQuery('index_id');
// Set requestHandler for the query type.
$config = $query->getIndex()->getDatasource('solr_document')->getConfiguration();
if (!empty($config['advanced']['request_handler'])) {
$solarium_query->addParam('qt', $config['advanced']['request_handler']);
}
}
/**
* Implements hook_search_api_solr_search_results_alter().
*/
function search_api_solr_datasource_search_api_solr_search_results_alter(ResultSetInterface $results, QueryInterface $query, SolariumResult $resultset) {
// Do not alter the results if the index does not use the solr_document
// datasource.
$datasources = $query->getIndex()->getDatasources();
if (!isset($datasources['solr_document'])) {
return;
}
/** @var \Drupal\search_api_solr_datasource\SolrDocumentFactoryInterface $solr_document_factory */
$solr_document_factory = \Drupal::getContainer()->get('solr_document.factory');
/** @var \Drupal\search_api\Item\Item $item */
foreach ($results->getResultItems() as $item) {
// Create the typed data object for the Item immediately after the query has
// been run. Doing this now can prevent the Search API from having to query
// for individual documents later.
$item->setOriginalObject($solr_document_factory->create($item));
// Prepend each item's itemId with the datasource ID. A lot of the Search
// API assumes that the item IDs are formatted as 'datasouce_id/entity_id.'
// Of course, the ID numbers of external Solr documents will not have this
// pattern and the datasource must be added. Reflect into the class to set
// the itemId.
$reflection = new \ReflectionClass($item);
$id_property = $reflection->getProperty('itemId');
$id_property->setAccessible(TRUE);
$id_property->setValue($item, 'solr_document/' . $item->getId());
}
}
/**
* Implements hook_views_data_alter().
*
* Remove fields from solr_document datasources from the views data. Datasource
* fields that have been added to the index would be duplicated in the Views Add
* fields list. Fields that aren't added to the index can't be displayed.
*/
function search_api_solr_datasource_views_data_alter(array &$data) {
foreach ($data as $key => $fields) {
if (preg_match('/search_api_datasource_(.+)_solr_document/', $key)) {
unset($data[$key]);
}
}
}