mirror of
https://github.com/silverstripe/silverstripe-fulltextsearch
synced 2024-10-22 14:05:29 +02:00
Merge remote-tracking branch 'upstream/master' into compat4/btasker
This commit is contained in:
commit
0de6f52b1f
@ -1,4 +1,4 @@
|
||||
# See https://github.com/silverstripe-labs/silverstripe-travis-support for setup details
|
||||
# See https://github.com/silverstripe/silverstripe-travis-support for setup details
|
||||
|
||||
language: php
|
||||
|
||||
@ -16,8 +16,6 @@ matrix:
|
||||
include:
|
||||
- php: 5.6
|
||||
env: DB=MYSQL CORE_RELEASE=4
|
||||
- php: 5.6
|
||||
# env: DB=MYSQL CORE_RELEASE=4 SUBSITES=1
|
||||
- php: 5.6
|
||||
env: DB=MYSQL CORE_RELEASE=4 QUEUEDJOBS=1
|
||||
- php: 7.0
|
||||
@ -35,7 +33,7 @@ matrix:
|
||||
|
||||
before_script:
|
||||
- composer self-update || true
|
||||
- git clone git://github.com/silverstripe-labs/silverstripe-travis-support.git ~/travis-support
|
||||
- git clone git://github.com/silverstripe/silverstripe-travis-support.git ~/travis-support
|
||||
- "if [ \"$SUBSITES\" = \"\" -a \"$QUEUEDJOBS\" = \"\" ]; then php ~/travis-support/travis_setup.php --source `pwd` --target ~/builds/ss; fi"
|
||||
# - "if [ \"$SUBSITES\" = \"1\" ]; then php ~/travis-support/travis_setup.php --source `pwd` --target ~/builds/ss --require silverstripe/subsites; fi"
|
||||
- "if [ \"$QUEUEDJOBS\" = \"1\" ]; then php ~/travis-support/travis_setup.php --source `pwd` --target ~/builds/ss --require silverstripe/queuedjobs; fi"
|
||||
|
@ -51,6 +51,27 @@ abstract class SearchIndex extends ViewableData
|
||||
*/
|
||||
private static $hide_ancestor;
|
||||
|
||||
/**
|
||||
* Used to separate class name and relation name in the sources array
|
||||
* this string must not be present in class name
|
||||
* @var string
|
||||
* @config
|
||||
*/
|
||||
private static $class_delimiter = '_|_';
|
||||
|
||||
/**
|
||||
* This is used to clean the source name from suffix
|
||||
* suffixes are needed to support multiple relations with the same name on different page types
|
||||
* @param string $source
|
||||
* @return string
|
||||
*/
|
||||
protected function getSourceName($source)
|
||||
{
|
||||
$source = explode(self::config()->get('class_delimiter'), $source);
|
||||
|
||||
return $source[0];
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
@ -71,6 +92,9 @@ abstract class SearchIndex extends ViewableData
|
||||
/**
|
||||
* Examines the classes this index is built on to try and find defined fields in the class hierarchy for those classes.
|
||||
* Looks for db and viewable-data fields, although can't nessecarily find type for viewable-data fields.
|
||||
* If multiple classes have a relation with the same name all of these will be included in the search index
|
||||
* Note that only classes that have the relations uninherited (defined in them) will be listed
|
||||
* this is because inherited relations do not need to be processed by index explicitly
|
||||
*/
|
||||
public function fieldData($field, $forceType = null, $extraOptions = array())
|
||||
{
|
||||
@ -91,21 +115,37 @@ abstract class SearchIndex extends ViewableData
|
||||
foreach ($lookups as $lookup) {
|
||||
$next = array();
|
||||
|
||||
foreach ($sources as $source => $options) {
|
||||
$class = null;
|
||||
foreach ($sources as $source => $baseOptions) {
|
||||
$source = $this->getSourceName($source);
|
||||
|
||||
foreach (SearchIntrospection::hierarchy($source, $options['include_children']) as $dataclass) {
|
||||
foreach (SearchIntrospection::hierarchy($source, $baseOptions['include_children']) as $dataclass) {
|
||||
$class = null;
|
||||
$options = $baseOptions;
|
||||
$singleton = singleton($dataclass);
|
||||
$schema = DataObject::getSchema();
|
||||
$className = $singleton->getClassName();
|
||||
|
||||
if ($hasOne = $schema->hasOneComponent($className, $lookup)) {
|
||||
// we only want to include base class for relation, omit classes that inherited the relation
|
||||
$relationList = Config::inst()->get($dataclass, 'has_one', Config::UNINHERITED);
|
||||
$relationList = (!is_null($relationList)) ? $relationList : [];
|
||||
if (!array_key_exists($lookup, $relationList)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$class = $hasOne;
|
||||
$options['lookup_chain'][] = array(
|
||||
'call' => 'method', 'method' => $lookup,
|
||||
'through' => 'has_one', 'class' => $dataclass, 'otherclass' => $class, 'foreignkey' => "{$lookup}ID"
|
||||
);
|
||||
} elseif ($hasMany = $schema->hasManyComponent($className, $lookup)) {
|
||||
// we only want to include base class for relation, omit classes that inherited the relation
|
||||
$relationList = Config::inst()->get($dataclass, 'has_many', Config::UNINHERITED);
|
||||
$relationList = (!is_null($relationList)) ? $relationList : [];
|
||||
if (!array_key_exists($lookup, $relationList)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$class = $hasMany;
|
||||
$options['multi_valued'] = true;
|
||||
$options['lookup_chain'][] = array(
|
||||
@ -113,6 +153,13 @@ abstract class SearchIndex extends ViewableData
|
||||
'through' => 'has_many', 'class' => $dataclass, 'otherclass' => $class, 'foreignkey' => $schema->getRemoteJoinField($className, $lookup, 'has_many')
|
||||
);
|
||||
} elseif ($manyMany = $schema->manyManyComponent($className, $lookup)) {
|
||||
// we only want to include base class for relation, omit classes that inherited the relation
|
||||
$relationList = Config::inst()->get($dataclass, 'many_many', Config::UNINHERITED);
|
||||
$relationList = (!is_null($relationList)) ? $relationList : [];
|
||||
if (!array_key_exists($lookup, $relationList)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$class = $manyMany[2];
|
||||
$options['multi_valued'] = true;
|
||||
$options['lookup_chain'][] = array(
|
||||
@ -125,8 +172,10 @@ abstract class SearchIndex extends ViewableData
|
||||
if (!isset($options['origin'])) {
|
||||
$options['origin'] = $dataclass;
|
||||
}
|
||||
$next[$class] = $options;
|
||||
continue 2;
|
||||
|
||||
// we add suffix here to prevent the relation to be overwritten by other instances
|
||||
// all sources lookups must clean the source name before reading it via getSourceName()
|
||||
$next[$class . self::config()->get('class_delimiter') . $dataclass] = $options;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -139,6 +188,7 @@ abstract class SearchIndex extends ViewableData
|
||||
}
|
||||
|
||||
foreach ($sources as $class => $options) {
|
||||
$class = $this->getSourceName($class);
|
||||
$dataclasses = SearchIntrospection::hierarchy($class, $options['include_children']);
|
||||
|
||||
while (count($dataclasses)) {
|
||||
|
@ -60,7 +60,7 @@ class SearchUpdateCommitJobProcessor implements QueuedJob
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $dirty_indexes = true;
|
||||
public static $dirty_indexes = array();
|
||||
|
||||
/**
|
||||
* If solrindex::commit has already been performed, but additional commits are necessary,
|
||||
|
@ -30,6 +30,10 @@ class Solr_Configure extends Solr_BuildTask
|
||||
->error("Failure: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($e)) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -87,4 +91,3 @@ class Solr_Configure extends Solr_BuildTask
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.x-dev"
|
||||
"dev-master": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
|
@ -140,7 +140,6 @@
|
||||
</analyzer>
|
||||
<analyzer type="query">
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
<filter class="solr.StopFilterFactory"
|
||||
ignoreCase="true"
|
||||
words="stopwords.txt"
|
||||
@ -149,6 +148,7 @@
|
||||
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
<filter class="solr.PorterStemFilterFactory"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
@ -166,11 +166,11 @@
|
||||
</analyzer>
|
||||
<analyzer type="query">
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true"/>
|
||||
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
<filter class="solr.PorterStemFilterFactory"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
@ -180,7 +180,6 @@
|
||||
<fieldType name="textTight" class="solr.TextField" positionIncrementGap="100" >
|
||||
<analyzer>
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="false"/>
|
||||
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/>
|
||||
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="0" generateNumberParts="0" catenateWords="1" catenateNumbers="1" catenateAll="0"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
@ -189,6 +188,7 @@
|
||||
<!-- this filter can remove any duplicate tokens that appear at the same position - sometimes
|
||||
possible with WordDelimiterFilter in conjuncton with stemming. -->
|
||||
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="false"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
|
||||
@ -214,7 +214,6 @@
|
||||
</analyzer>
|
||||
<analyzer type="query">
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
<filter class="solr.StopFilterFactory"
|
||||
ignoreCase="true"
|
||||
words="stopwords.txt"
|
||||
@ -222,6 +221,7 @@
|
||||
/>
|
||||
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="0"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
|
||||
@ -240,7 +240,6 @@
|
||||
</analyzer>
|
||||
<analyzer type="query">
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
<filter class="solr.StopFilterFactory"
|
||||
ignoreCase="true"
|
||||
words="stopwords.txt"
|
||||
@ -248,6 +247,7 @@
|
||||
/>
|
||||
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="0"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
|
||||
|
@ -140,7 +140,6 @@
|
||||
<analyzer type="query">
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.KeywordRepeatFilterFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
<filter class="solr.StopFilterFactory"
|
||||
ignoreCase="true"
|
||||
words="stopwords.txt"
|
||||
@ -150,6 +149,7 @@
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
|
||||
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
|
||||
@ -166,12 +166,12 @@
|
||||
<analyzer type="query">
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.KeywordRepeatFilterFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true"/>
|
||||
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
|
||||
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
|
||||
@ -180,7 +180,6 @@
|
||||
<fieldType name="textTight" class="solr.TextField" positionIncrementGap="100" >
|
||||
<analyzer>
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="false"/>
|
||||
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/>
|
||||
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="0" generateNumberParts="0" catenateWords="1" catenateNumbers="1" catenateAll="0"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
@ -189,6 +188,7 @@
|
||||
<!-- this filter can remove any duplicate tokens that appear at the same position - sometimes
|
||||
possible with WordDelimiterFilter in conjuncton with stemming. -->
|
||||
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="false"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
|
||||
@ -225,7 +225,6 @@
|
||||
</analyzer>
|
||||
<analyzer type="query">
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
<filter class="solr.StopFilterFactory"
|
||||
ignoreCase="true"
|
||||
words="stopwords.txt"
|
||||
@ -233,6 +232,7 @@
|
||||
/>
|
||||
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="0"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
|
||||
@ -251,7 +251,6 @@
|
||||
</analyzer>
|
||||
<analyzer type="query">
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
<filter class="solr.StopFilterFactory"
|
||||
ignoreCase="true"
|
||||
words="stopwords.txt"
|
||||
@ -259,6 +258,7 @@
|
||||
/>
|
||||
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="0"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
|
||||
|
@ -203,6 +203,20 @@ To allow searches on words containing numeric tokens, you'll need to update your
|
||||
|
||||
Update your index to point to your overloaded template using the method described above.
|
||||
|
||||
#### Searching for macrons and other Unicode characters
|
||||
|
||||
The “ASCIIFoldingFilterFactory” filter converts alphabetic, numeric, and symbolic Unicode characters which are not in the Basic Latin Unicode block (the first 127 ASCII characters) to their ASCII equivalents, if one exists.
|
||||
|
||||
Find the fields in your overloaded `types.ss` that you want to enable this behaviour in. EG:
|
||||
|
||||
<fieldType name="htmltext" class="solr.TextField" ... >
|
||||
|
||||
Add the following to both its index analyzer and query analyzer records.
|
||||
|
||||
<filter class="solr.ASCIIFoldingFilterFactory"/>
|
||||
|
||||
Update your index to point to your overloaded template using the method described above.
|
||||
|
||||
### Spell Checking ("Did you mean...")
|
||||
|
||||
Solr has various spell checking strategies (see the ["SpellCheckComponent" docs](http://wiki.apache.org/solr/SpellCheckComponent)), all of which are configured through `solrconfig.xml`.
|
||||
|
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\FullTextSearch\Tests\SearchUpdaterTest;
|
||||
|
||||
/**
|
||||
* Used to test inherited ambiguous relationships.
|
||||
*/
|
||||
class SearchUpdaterTest_ExtendedContainer extends SearchUpdaterTest_OtherContainer
|
||||
{
|
||||
private static $db = array(
|
||||
'SomeField' => 'Varchar',
|
||||
);
|
||||
}
|
@ -15,6 +15,7 @@ class SearchUpdaterTest_HasMany extends DataObject
|
||||
private static $table_name = 'SearchUpdaterTest_HasMany';
|
||||
|
||||
private static $has_one = array(
|
||||
'HasManyContainer' => SearchUpdaterTest_Container::class
|
||||
'HasManyContainer' => SearchUpdaterTest_Container::class,
|
||||
'HasManyOtherContainer' => SearchUpdaterTest_OtherContainer::class,
|
||||
);
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ class SearchUpdaterTest_HasOne extends DataObject
|
||||
private static $table_name = 'SearchUpdaterTest_HasOne';
|
||||
|
||||
private static $has_many = array(
|
||||
'HasManyContainers' => SearchUpdaterTest_Container::class
|
||||
'HasManyContainers' => SearchUpdaterTest_Container::class,
|
||||
'HasManyOtherContainer' => SearchUpdaterTest_OtherContainer::class,
|
||||
);
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
namespace SilverStripe\FullTextSearch\Tests\SearchUpdaterTest;
|
||||
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_Container;
|
||||
|
||||
class SearchUpdaterTest_ManyMany extends DataObject
|
||||
{
|
||||
@ -15,6 +14,7 @@ class SearchUpdaterTest_ManyMany extends DataObject
|
||||
private static $table_name = 'SearchUpdaterTest_ManyMany';
|
||||
|
||||
private static $belongs_many_many = array(
|
||||
'ManyManyContainer' => SearchUpdaterTest_Container::class
|
||||
'ManyManyContainer' => SearchUpdaterTest_Container::class,
|
||||
'ManyManyOtherContainer' => SearchUpdaterTest_OtherContainer::class,
|
||||
);
|
||||
}
|
||||
|
19
tests/SearchUpdaterTest/SearchUpdaterTest_OtherContainer.php
Normal file
19
tests/SearchUpdaterTest/SearchUpdaterTest_OtherContainer.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\FullTextSearch\Tests\SearchUpdaterTest;
|
||||
|
||||
use SilverStripe\ORM\DataObject;
|
||||
|
||||
/**
|
||||
* Used to test ambiguous relationships.
|
||||
*/
|
||||
class SearchUpdaterTest_OtherContainer extends DataObject
|
||||
{
|
||||
private static $has_many = [
|
||||
'HasManyObjects' => SearchUpdaterTest_HasMany::class,
|
||||
];
|
||||
|
||||
private static $many_many = [
|
||||
'ManyManyObjects' => SearchUpdaterTest_ManyMany::class,
|
||||
];
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
<?php
|
||||
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
use SilverStripe\FullTextSearch\Tests\SolrIndexTest\SolrIndexTest_AmbiguousRelationIndex;
|
||||
use SilverStripe\FullTextSearch\Tests\SolrIndexTest\SolrIndexTest_AmbiguousRelationInheritedIndex;
|
||||
use SilverStripe\FullTextSearch\Tests\SolrIndexTest\SolrIndexTest_FakeIndex;
|
||||
use SilverStripe\FullTextSearch\Tests\SolrIndexTest\SolrIndexTest_FakeIndex2;
|
||||
use SilverStripe\FullTextSearch\Tests\SolrIndexTest\SolrIndexTest_BoostedIndex;
|
||||
@ -9,6 +11,7 @@ use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_Contai
|
||||
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_HasOne;
|
||||
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_HasMany;
|
||||
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_ManyMany;
|
||||
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_OtherContainer;
|
||||
use SilverStripe\Core\Config\Config;
|
||||
use SilverStripe\Control\Director;
|
||||
use SilverStripe\FullTextSearch\Search\Queries\SearchQuery;
|
||||
@ -50,6 +53,64 @@ class SolrIndexTest extends SapphireTest
|
||||
$this->assertEquals(SearchUpdaterTest_ManyMany::class, $data['class']);
|
||||
}
|
||||
|
||||
public function testFieldDataAmbiguousHasMany()
|
||||
{
|
||||
$index = new SolrIndexTest_AmbiguousRelationIndex();
|
||||
$data = $index->fieldData('HasManyObjects.Field1');
|
||||
|
||||
$this->assertArrayHasKey('SearchUpdaterTest_Container_HasManyObjects_Field1', $data);
|
||||
$this->assertArrayHasKey('SearchUpdaterTest_OtherContainer_HasManyObjects_Field1', $data);
|
||||
|
||||
$dataContainer = $data['SearchUpdaterTest_Container_HasManyObjects_Field1'];
|
||||
$this->assertEquals(SearchUpdaterTest_Container::class, $dataContainer['origin']);
|
||||
$this->assertEquals(SearchUpdaterTest_Container::class, $dataContainer['base']);
|
||||
$this->assertEquals(SearchUpdaterTest_HasMany::class, $dataContainer['class']);
|
||||
|
||||
$dataOtherContainer = $data['SearchUpdaterTest_OtherContainer_HasManyObjects_Field1'];
|
||||
$this->assertEquals(SearchUpdaterTest_OtherContainer::class, $dataOtherContainer['origin']);
|
||||
$this->assertEquals(SearchUpdaterTest_OtherContainer::class, $dataOtherContainer['base']);
|
||||
$this->assertEquals(SearchUpdaterTest_HasMany::class, $dataOtherContainer['class']);
|
||||
}
|
||||
|
||||
public function testFieldDataAmbiguousManyMany()
|
||||
{
|
||||
$index = new SolrIndexTest_AmbiguousRelationIndex();
|
||||
$data = $index->fieldData('ManyManyObjects.Field1');
|
||||
|
||||
$this->assertArrayHasKey('SearchUpdaterTest_Container_ManyManyObjects_Field1', $data);
|
||||
$this->assertArrayHasKey('SearchUpdaterTest_OtherContainer_ManyManyObjects_Field1', $data);
|
||||
|
||||
$dataContainer = $data['SearchUpdaterTest_Container_ManyManyObjects_Field1'];
|
||||
$this->assertEquals(SearchUpdaterTest_Container::class, $dataContainer['origin']);
|
||||
$this->assertEquals(SearchUpdaterTest_Container::class, $dataContainer['base']);
|
||||
$this->assertEquals(SearchUpdaterTest_ManyMany::class, $dataContainer['class']);
|
||||
|
||||
$dataOtherContainer = $data['SearchUpdaterTest_OtherContainer_ManyManyObjects_Field1'];
|
||||
$this->assertEquals(SearchUpdaterTest_OtherContainer::class, $dataOtherContainer['origin']);
|
||||
$this->assertEquals(SearchUpdaterTest_OtherContainer::class, $dataOtherContainer['base']);
|
||||
$this->assertEquals(SearchUpdaterTest_ManyMany::class, $dataOtherContainer['class']);
|
||||
}
|
||||
|
||||
public function testFieldDataAmbiguousManyManyInherited()
|
||||
{
|
||||
$index = new SolrIndexTest_AmbiguousRelationInheritedIndex();
|
||||
$data = $index->fieldData('ManyManyObjects.Field1');
|
||||
|
||||
$this->assertArrayHasKey('SearchUpdaterTest_Container_ManyManyObjects_Field1', $data);
|
||||
$this->assertArrayHasKey('SearchUpdaterTest_OtherContainer_ManyManyObjects_Field1', $data);
|
||||
$this->assertArrayNotHasKey('SearchUpdaterTest_ExtendedContainer_ManyManyObjects_Field1', $data);
|
||||
|
||||
$dataContainer = $data['SearchUpdaterTest_Container_ManyManyObjects_Field1'];
|
||||
$this->assertEquals(SearchUpdaterTest_Container::class, $dataContainer['origin']);
|
||||
$this->assertEquals(SearchUpdaterTest_Container::class, $dataContainer['base']);
|
||||
$this->assertEquals(SearchUpdaterTest_ManyMany::class, $dataContainer['class']);
|
||||
|
||||
$dataOtherContainer = $data['SearchUpdaterTest_OtherContainer_ManyManyObjects_Field1'];
|
||||
$this->assertEquals(SearchUpdaterTest_OtherContainer::class, $dataOtherContainer['origin']);
|
||||
$this->assertEquals(SearchUpdaterTest_OtherContainer::class, $dataOtherContainer['base']);
|
||||
$this->assertEquals(SearchUpdaterTest_ManyMany::class, $dataOtherContainer['class']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test boosting on SearchQuery
|
||||
*/
|
||||
@ -62,7 +123,8 @@ class SolrIndexTest extends SapphireTest
|
||||
|
||||
$serviceMock->expects($this->once())
|
||||
->method('search')
|
||||
->with($this->equalTo('+(Field1:term^1.5 OR HasOneObject_Field1:term^3)'),
|
||||
->with(
|
||||
$this->equalTo('+(Field1:term^1.5 OR HasOneObject_Field1:term^3)'),
|
||||
$this->anything(),
|
||||
$this->anything(),
|
||||
$this->anything(),
|
||||
@ -93,7 +155,8 @@ class SolrIndexTest extends SapphireTest
|
||||
|
||||
$serviceMock->expects($this->once())
|
||||
->method('search')
|
||||
->with($this->equalTo('+term'),
|
||||
->with(
|
||||
$this->equalTo('+term'),
|
||||
$this->anything(),
|
||||
$this->anything(),
|
||||
$this->equalTo(['qf' => SearchUpdaterTest_Container::class . '_Field1^1.5 ' . SearchUpdaterTest_Container::class . '_Field2^2.1 _text',
|
||||
|
26
tests/SolrIndexTest/SolrIndexTest_AmbiguousRelationIndex.php
Normal file
26
tests/SolrIndexTest/SolrIndexTest_AmbiguousRelationIndex.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\FullTextSearch\Tests\SolrIndexTest;
|
||||
|
||||
use SilverStripe\FullTextSearch\Solr\SolrIndex;
|
||||
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_Container;
|
||||
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_OtherContainer;
|
||||
|
||||
class SolrIndexTest_AmbiguousRelationIndex extends SolrIndex
|
||||
{
|
||||
protected function getStoredDefault()
|
||||
{
|
||||
// Override isDev defaulting to stored
|
||||
return 'false';
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->addClass(SearchUpdaterTest_Container::class);
|
||||
$this->addClass(SearchUpdaterTest_OtherContainer::class);
|
||||
|
||||
// These relationships exist on both classes
|
||||
$this->addFilterField('HasManyObjects.Field1');
|
||||
$this->addFilterField('ManyManyObjects.Field1');
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\FullTextSearch\Tests\SolrIndexTest;
|
||||
|
||||
use SilverStripe\FullTextSearch\Solr\SolrIndex;
|
||||
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_Container;
|
||||
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_ExtendedContainer;
|
||||
|
||||
class SolrIndexTest_AmbiguousRelationInheritedIndex extends SolrIndex
|
||||
{
|
||||
protected function getStoredDefault()
|
||||
{
|
||||
// Override isDev defaulting to stored
|
||||
return 'false';
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->addClass(SearchUpdaterTest_Container::class);
|
||||
// this one has not the relation defined in it's class but is rather inherited from parent
|
||||
// note that even if we do not include it's parent class the fields will be properly added
|
||||
$this->addClass(SearchUpdaterTest_ExtendedContainer::class);
|
||||
|
||||
// These relationships exist on both classes
|
||||
$this->addFilterField('HasManyObjects.Field1');
|
||||
$this->addFilterField('ManyManyObjects.Field1');
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user