
In previous articles, I told you how to install and configure Apache Solr to organize a search on Drupal. In addition, we learned how to add fields and search index settings. In this article I will talk about how to add your own fields and settings, if the standard is not enough.
For those who have not read the previous parts, I recommend reading them for a better understanding of the material.
Fields
So let's start by adding fields. Suppose the nodes that you index have reference to a dictionary with geolocation data. Its structure looks like this:

')
The task is to index only the values ​​of the first level, i.e. areas to which the node belongs. If we add the corresponding field to the index, all terms will be indexed, regardless of the level. Therefore, we need to add our own field. For this we need two functions. The first is entity_property_info_alter hook. In this hook you can add new fields for the entity. So, add a new field for the node.
function test_search_entity_property_info_alter(&$info) { $info['node']['properties']['geo_first_level'] = array( 'type' => 'text', 'label' => t('Geo 1 level'), 'getter callback' => 'test_search_geo_first_level_getter_callback', ); }
The second function is getter callback, in this case test_search_geo_first_level_getter_callback. It should return the value for our field at the time of the node's indexing. This value will be stored in the index.
function test_search_geo_first_level_getter_callback($item) { if ($geo = field_get_items('node', $item, 'field_geo')) { $parents = taxonomy_get_parents($geo[0]['tid']); if (empty($parents)) { if ($term = taxonomy_term_load($geo[0]['tid'])) { return $term->name; } } } return NULL; }
As $ item the indexed entity will be passed, in our case it is the node object. We do a small check on whether this node contains, the term of the 1st level or not, and return the name of the term as an index value.
Now go to the index settings and select the Fields tab.

Our new field is already available for indexing. Do not forget to add it to the list of fields by which you can search in the view settings.
Sometimes it may be necessary to index multiple values ​​for a field. To do this, in the entity_property_info_alter hook specify 'type' => 'list', and in the getter callback you will need to return an array of values.
For example,
return array('', '-', '');
Filters
Now we will try to add a filter by which it will be possible to select nodes for indexing. The filter will perform a similar function - allow indexing only those nodes that have a reference to the first-level term from the geo dictionary. To do this, in the search_api_alter_callback_info hook, we will declare our filter.
function test_search_search_api_alter_callback_info() { $callbacks['search_api_alter_geo_level'] = array( 'name' => t('Filter by level of geo'), 'description' => t('Index only nodes with first level of term from vocabulary geo'), 'class' => 'SearchApiAlterGeoLevelFilter',
I placed the file with the filter class in the includes folder of the test_search module. Do not forget to connect it in the .info file of your module. For example:
files[] = includes/callback_geo_level.inc
Below is the code of the filter itself.
<?php class SearchApiAlterGeoLevelFilter extends SearchApiAbstractAlterCallback { public function alterItems(array &$items) { foreach ($items as $id => $item) { if ($geo = field_get_items('node', $item, 'field_geo')) { $parents = taxonomy_get_parents($geo[0]['tid']);
In the alterItems function, we simply exclude elements that have terms not of the first level. These items will not be indexed.
To enable the filter, you need to clean the cache and go to the workflow tab in the index settings.

After you enable the filter, you must re-index the content again. Now only those nodes that have the term of the first level dictionary will get into the index.