Merge pull request #105 from Codappix/feature/configure-fields-to-search

FEATURE: Provide new feature to configure fields to search in
This commit is contained in:
Daniel Siepmann 2017-12-04 21:36:29 +01:00 committed by GitHub
commit 9cad547b09
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 123 additions and 51 deletions

View file

@ -99,20 +99,18 @@ class QueryFactory
return; return;
} }
$query = ArrayUtility::setValueByPath( $matchExpression = [
$query, 'type' => 'most_fields',
'query.bool.must.0.match._all.query', 'query' => $searchRequest->getSearchTerm(),
$searchRequest->getSearchTerm() 'fields' => GeneralUtility::trimExplode(',', $this->configuration->get('searching.fields.query')),
); ];
$minimumShouldMatch = $this->configuration->getIfExists('searching.minimumShouldMatch'); $minimumShouldMatch = $this->configuration->getIfExists('searching.minimumShouldMatch');
if ($minimumShouldMatch) { if ($minimumShouldMatch) {
$query = ArrayUtility::setValueByPath( $matchExpression['minimum_should_match'] = $minimumShouldMatch;
$query,
'query.bool.must.0.match._all.minimum_should_match',
$minimumShouldMatch
);
} }
$query = ArrayUtility::setValueByPath($query, 'query.bool.must.0.multi_match', $matchExpression);
} }
protected function addBoosts(SearchRequestInterface $searchRequest, array &$query) protected function addBoosts(SearchRequestInterface $searchRequest, array &$query)

View file

@ -21,6 +21,12 @@ plugin {
abstractFields = {$plugin.tx_searchcore.settings.indexing.pages.abstractFields} abstractFields = {$plugin.tx_searchcore.settings.indexing.pages.abstractFields}
} }
} }
searching {
fields {
query = _all
}
}
} }
} }
} }

View file

@ -151,7 +151,18 @@ filtering. This way you can use arbitrary filter names and map them to existing
fields fields
------ ------
Defines the fields to fetch from elasticsearch. Two sub entries exist: Defines the fields to fetch and search from elasticsearch. With the following sub keys:
``query`` defines the fields to search in. Default is ``_all`` from 5.x times of elasticsearch.
Configure a comma separated list of fields to search in. This is necessary if you have configured
special mapping for some fields, or just want to search some fields.
The most hits get ranked highest. The following is an example configuration::
fields {
query = _all, city
}
The following sub properties configure the fields to fetch from elasticsearch:
First ``stored_fields`` which is a list of comma separated fields which actually exist and will be First ``stored_fields`` which is a list of comma separated fields which actually exist and will be
added. Typically you will use ``_source`` to fetch the whole indexed fields. added. Typically you will use ``_source`` to fetch the whole indexed fields.

View file

@ -42,6 +42,10 @@ plugin {
field = CType field = CType
} }
} }
fields {
query = _all
}
} }
} }
} }

View file

@ -56,9 +56,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
{ {
$searchRequest = new SearchRequest('SearchWord'); $searchRequest = new SearchRequest('SearchWord');
$this->configuration->expects($this->any()) $this->configureConfigurationMockWithDefault();
->method('get')
->will($this->throwException(new InvalidArgumentException));
$query = $this->subject->create($searchRequest); $query = $this->subject->create($searchRequest);
$this->assertInstanceOf( $this->assertInstanceOf(
@ -73,9 +71,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
*/ */
public function filterIsAddedToQuery() public function filterIsAddedToQuery()
{ {
$this->configuration->expects($this->any()) $this->configureConfigurationMockWithDefault();
->method('get')
->will($this->throwException(new InvalidArgumentException));
$searchRequest = new SearchRequest('SearchWord'); $searchRequest = new SearchRequest('SearchWord');
$searchRequest->setFilter(['field' => 'content']); $searchRequest->setFilter(['field' => 'content']);
@ -95,9 +91,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
*/ */
public function emptyFilterIsNotAddedToQuery() public function emptyFilterIsNotAddedToQuery()
{ {
$this->configuration->expects($this->any()) $this->configureConfigurationMockWithDefault();
->method('get')
->will($this->throwException(new InvalidArgumentException));
$searchRequest = new SearchRequest('SearchWord'); $searchRequest = new SearchRequest('SearchWord');
$searchRequest->setFilter([ $searchRequest->setFilter([
@ -122,9 +116,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
*/ */
public function facetsAreAddedToQuery() public function facetsAreAddedToQuery()
{ {
$this->configuration->expects($this->any()) $this->configureConfigurationMockWithDefault();
->method('get')
->will($this->throwException(new InvalidArgumentException));
$searchRequest = new SearchRequest('SearchWord'); $searchRequest = new SearchRequest('SearchWord');
$searchRequest->addFacet(new FacetRequest('Identifier', 'FieldName')); $searchRequest->addFacet(new FacetRequest('Identifier', 'FieldName'));
$searchRequest->addFacet(new FacetRequest('Identifier 2', 'FieldName 2')); $searchRequest->addFacet(new FacetRequest('Identifier 2', 'FieldName 2'));
@ -153,9 +145,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
*/ */
public function sizeIsAddedToQuery() public function sizeIsAddedToQuery()
{ {
$this->configuration->expects($this->any()) $this->configureConfigurationMockWithDefault();
->method('get')
->will($this->throwException(new InvalidArgumentException));
$searchRequest = new SearchRequest('SearchWord'); $searchRequest = new SearchRequest('SearchWord');
$searchRequest->setLimit(45); $searchRequest->setLimit(45);
$searchRequest->setOffset(35); $searchRequest->setOffset(35);
@ -179,9 +169,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
public function searchTermIsAddedToQuery() public function searchTermIsAddedToQuery()
{ {
$searchRequest = new SearchRequest('SearchWord'); $searchRequest = new SearchRequest('SearchWord');
$this->configuration->expects($this->any()) $this->configureConfigurationMockWithDefault();
->method('get')
->will($this->throwException(new InvalidArgumentException));
$query = $this->subject->create($searchRequest); $query = $this->subject->create($searchRequest);
$this->assertSame( $this->assertSame(
@ -189,9 +177,11 @@ class QueryFactoryTest extends AbstractUnitTestCase
'bool' => [ 'bool' => [
'must' => [ 'must' => [
[ [
'match' => [ 'multi_match' => [
'_all' => [ 'type' => 'most_fields',
'query' => 'SearchWord', 'query' => 'SearchWord',
'fields' => [
'_all',
], ],
], ],
], ],
@ -219,9 +209,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
'50%', '50%',
null null
)); ));
$this->configuration->expects($this->any()) $this->configureConfigurationMockWithDefault();
->method('get')
->will($this->throwException(new InvalidArgumentException));
$query = $this->subject->create($searchRequest); $query = $this->subject->create($searchRequest);
$this->assertArraySubset( $this->assertArraySubset(
@ -229,10 +217,13 @@ class QueryFactoryTest extends AbstractUnitTestCase
'bool' => [ 'bool' => [
'must' => [ 'must' => [
[ [
'match' => [ 'multi_match' => [
'_all' => [ 'type' => 'most_fields',
'minimum_should_match' => '50%', 'query' => 'SearchWord',
'fields' => [
'_all',
], ],
'minimum_should_match' => '50%',
], ],
], ],
], ],
@ -253,12 +244,14 @@ class QueryFactoryTest extends AbstractUnitTestCase
$this->configuration->expects($this->any()) $this->configuration->expects($this->any())
->method('get') ->method('get')
->withConsecutive( ->withConsecutive(
['searching.fields.query'],
['searching.boost'], ['searching.boost'],
['searching.fields.stored_fields'], ['searching.fields.stored_fields'],
['searching.fields.script_fields'], ['searching.fields.script_fields'],
['searching.fieldValueFactor'] ['searching.fieldValueFactor']
) )
->will($this->onConsecutiveCalls( ->will($this->onConsecutiveCalls(
'_all',
[ [
'search_title' => 3, 'search_title' => 3,
'search_abstract' => 1.5, 'search_abstract' => 1.5,
@ -308,12 +301,14 @@ class QueryFactoryTest extends AbstractUnitTestCase
$this->configuration->expects($this->any()) $this->configuration->expects($this->any())
->method('get') ->method('get')
->withConsecutive( ->withConsecutive(
['searching.fields.query'],
['searching.boost'], ['searching.boost'],
['searching.fields.stored_fields'], ['searching.fields.stored_fields'],
['searching.fields.script_fields'], ['searching.fields.script_fields'],
['searching.fieldValueFactor'] ['searching.fieldValueFactor']
) )
->will($this->onConsecutiveCalls( ->will($this->onConsecutiveCalls(
'_all',
$this->throwException(new InvalidArgumentException), $this->throwException(new InvalidArgumentException),
$this->throwException(new InvalidArgumentException), $this->throwException(new InvalidArgumentException),
$this->throwException(new InvalidArgumentException), $this->throwException(new InvalidArgumentException),
@ -328,9 +323,11 @@ class QueryFactoryTest extends AbstractUnitTestCase
'bool' => [ 'bool' => [
'must' => [ 'must' => [
[ [
'match' => [ 'multi_match' => [
'_all' => [ 'type' => 'most_fields',
'query' => 'SearchWord', 'query' => 'SearchWord',
'fields' => [
'_all',
], ],
], ],
], ],
@ -352,9 +349,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
{ {
$searchRequest = new SearchRequest(); $searchRequest = new SearchRequest();
$this->configuration->expects($this->any()) $this->configureConfigurationMockWithDefault();
->method('get')
->will($this->throwException(new InvalidArgumentException));
$query = $this->subject->create($searchRequest); $query = $this->subject->create($searchRequest);
$this->assertInstanceOf( $this->assertInstanceOf(
@ -364,6 +359,54 @@ class QueryFactoryTest extends AbstractUnitTestCase
); );
} }
/**
* @test
*/
public function configuredQueryFieldsAreAddedToQuery()
{
$searchRequest = new SearchRequest('SearchWord');
$this->configuration->expects($this->any())
->method('get')
->withConsecutive(
['searching.fields.query'],
['searching.boost'],
['searching.fields.stored_fields'],
['searching.fields.script_fields'],
['searching.fieldValueFactor']
)
->will($this->onConsecutiveCalls(
'_all, field1, field2',
$this->throwException(new InvalidArgumentException),
$this->throwException(new InvalidArgumentException),
$this->throwException(new InvalidArgumentException),
$this->throwException(new InvalidArgumentException)
));
$query = $this->subject->create($searchRequest);
$this->assertArraySubset(
[
'bool' => [
'must' => [
[
'multi_match' => [
'type' => 'most_fields',
'query' => 'SearchWord',
'fields' => [
'_all',
'field1',
'field2',
],
],
],
],
],
],
$query->toArray()['query'],
'Configured fields were not added to query as configured.'
);
}
/** /**
* @test * @test
*/ */
@ -433,12 +476,14 @@ class QueryFactoryTest extends AbstractUnitTestCase
$this->configuration->expects($this->any()) $this->configuration->expects($this->any())
->method('get') ->method('get')
->withConsecutive( ->withConsecutive(
['searching.fields.query'],
['searching.boost'], ['searching.boost'],
['searching.fields.stored_fields'], ['searching.fields.stored_fields'],
['searching.fields.script_fields'], ['searching.fields.script_fields'],
['searching.fieldValueFactor'] ['searching.fieldValueFactor']
) )
->will($this->onConsecutiveCalls( ->will($this->onConsecutiveCalls(
'_all',
$this->throwException(new InvalidArgumentException), $this->throwException(new InvalidArgumentException),
$this->throwException(new InvalidArgumentException), $this->throwException(new InvalidArgumentException),
[ [
@ -465,7 +510,6 @@ class QueryFactoryTest extends AbstractUnitTestCase
$query->toArray()['script_fields'], $query->toArray()['script_fields'],
'Script fields were not added to query as expected.' 'Script fields were not added to query as expected.'
); );
} }
/** /**
@ -522,9 +566,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
] ]
)); ));
$this->configuration->expects($this->any()) $this->configureConfigurationMockWithDefault();
->method('get')
->will($this->throwException(new InvalidArgumentException));
$query = $this->subject->create($searchRequest); $query = $this->subject->create($searchRequest);
$this->assertSame( $this->assertSame(
@ -559,9 +601,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
null null
)); ));
$this->configuration->expects($this->any()) $this->configureConfigurationMockWithDefault();
->method('get')
->will($this->throwException(new InvalidArgumentException));
$query = $this->subject->create($searchRequest); $query = $this->subject->create($searchRequest);
$this->assertTrue( $this->assertTrue(
@ -569,4 +609,17 @@ class QueryFactoryTest extends AbstractUnitTestCase
'Sort was added to query even if not configured.' 'Sort was added to query even if not configured.'
); );
} }
protected function configureConfigurationMockWithDefault()
{
$this->configuration->expects($this->any())
->method('get')
->will($this->returnCallback(function ($configName) {
if ($configName === 'searching.fields.query') {
return '_all';
}
throw new InvalidArgumentException();
}));
}
} }