mirror of
https://github.com/silverstripe/silverstripe-fulltextsearch
synced 2024-10-22 14:05:29 +02:00
Compare commits
No commits in common. "3" and "3.9.0-beta1" have entirely different histories.
3
...
3.9.0-beta
15
.github/workflows/ci.yml
vendored
15
.github/workflows/ci.yml
vendored
@ -1,15 +0,0 @@
|
|||||||
name: CI
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
ci:
|
|
||||||
name: CI
|
|
||||||
uses: silverstripe/gha-ci/.github/workflows/ci.yml@v1
|
|
||||||
with:
|
|
||||||
extra_jobs: |
|
|
||||||
- name_suffix: subsites
|
|
||||||
composer_require_extra: silverstripe/subsites:^2
|
|
16
.github/workflows/dispatch-ci.yml
vendored
16
.github/workflows/dispatch-ci.yml
vendored
@ -1,16 +0,0 @@
|
|||||||
name: Dispatch CI
|
|
||||||
|
|
||||||
on:
|
|
||||||
# At 2:10 PM UTC, only on Wednesday and Thursday
|
|
||||||
schedule:
|
|
||||||
- cron: '10 14 * * 3,4'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
dispatch-ci:
|
|
||||||
name: Dispatch CI
|
|
||||||
# Only run cron on the silverstripe account
|
|
||||||
if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule')
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Dispatch CI
|
|
||||||
uses: silverstripe/gha-dispatch-ci@v1
|
|
17
.github/workflows/keepalive.yml
vendored
17
.github/workflows/keepalive.yml
vendored
@ -1,17 +0,0 @@
|
|||||||
name: Keepalive
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
# The 4th of every month at 10:50am UTC
|
|
||||||
schedule:
|
|
||||||
- cron: '50 10 4 * *'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
keepalive:
|
|
||||||
name: Keepalive
|
|
||||||
# Only run cron on the silverstripe account
|
|
||||||
if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule')
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Keepalive
|
|
||||||
uses: silverstripe/gha-keepalive@v1
|
|
15
.scrutinizer.yml
Normal file
15
.scrutinizer.yml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
inherit: true
|
||||||
|
|
||||||
|
build:
|
||||||
|
nodes:
|
||||||
|
analysis:
|
||||||
|
tests:
|
||||||
|
override: [php-scrutinizer-run]
|
||||||
|
|
||||||
|
checks:
|
||||||
|
php:
|
||||||
|
code_rating: true
|
||||||
|
duplication: true
|
||||||
|
|
||||||
|
filter:
|
||||||
|
paths: [src/*, tests/*]
|
18
.travis.yml
Normal file
18
.travis.yml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
version: ~> 1.0
|
||||||
|
|
||||||
|
import:
|
||||||
|
- silverstripe/silverstripe-travis-shared:config/provision/standard-jobs-range.yml
|
||||||
|
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- COMPOSER_ROOT_VERSION="3.x-dev"
|
||||||
|
- REQUIRE_EXTRA="symbiote/silverstripe-queuedjobs:^4.0"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
include:
|
||||||
|
- php: 7.3
|
||||||
|
env:
|
||||||
|
- DB=MYSQL
|
||||||
|
- REQUIRE_INSTALLER=4.x-dev
|
||||||
|
- PHPUNIT_TEST=1
|
||||||
|
- REQUIRE_EXTRA="symbiote/silverstripe-queuedjobs:^4 silverstripe/subsites:^2"
|
@ -1,8 +0,0 @@
|
|||||||
[main]
|
|
||||||
host = https://www.transifex.com
|
|
||||||
|
|
||||||
[o:silverstripe:p:silverstripe-fulltextsearch:r:master]
|
|
||||||
file_filter = lang/<lang>.yml
|
|
||||||
source_file = lang/en.yml
|
|
||||||
source_lang = en
|
|
||||||
type = YML
|
|
11
README.md
11
README.md
@ -1,8 +1,11 @@
|
|||||||
# FullTextSearch module
|
# FullTextSearch module
|
||||||
|
|
||||||
[![CI](https://github.com/silverstripe/silverstripe-fulltextsearch/actions/workflows/ci.yml/badge.svg)](https://github.com/silverstripe/silverstripe-fulltextsearch/actions/workflows/ci.yml)
|
[![Build Status](https://api.travis-ci.com/silverstripe/silverstripe-fulltextsearch.svg?branch=3)](https://travis-ci.com/silverstripe/silverstripe-fulltextsearch)
|
||||||
|
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/silverstripe/silverstripe-fulltextsearch/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/silverstripe/silverstripe-fulltextsearch/?branch=master)
|
||||||
|
[![codecov](https://codecov.io/gh/silverstripe/silverstripe-fulltextsearch/branch/master/graph/badge.svg)](https://codecov.io/gh/silverstripe/silverstripe-fulltextsearch)
|
||||||
|
[![SilverStripe supported module](https://img.shields.io/badge/silverstripe-supported-0071C4.svg)](https://www.silverstripe.org/software/addons/silverstripe-commercially-supported-module-list/)
|
||||||
|
|
||||||
Adds support for fulltext search engines like Sphinx and Solr to Silverstripe CMS.
|
Adds support for fulltext search engines like Sphinx and Solr to SilverStripe CMS.
|
||||||
Compatible with PHP 7.2
|
Compatible with PHP 7.2
|
||||||
|
|
||||||
## Important notes when upgrading to fulltextsearch 3.7.0+
|
## Important notes when upgrading to fulltextsearch 3.7.0+
|
||||||
@ -83,9 +86,9 @@ it's recommended you update your implementation to call `SearchableService::isVi
|
|||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
* Silverstripe 4.0+
|
* SilverStripe 4.0+
|
||||||
|
|
||||||
**Note:** For Silverstripe 3.x, please use the [2.x release line](https://github.com/silverstripe/silverstripe-fulltextsearch/tree/2).
|
**Note:** For SilverStripe 3.x, please use the [2.x release line](https://github.com/silverstripe/silverstripe-fulltextsearch/tree/2).
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
5
_config.php
Normal file
5
_config.php
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use SilverStripe\Dev\Deprecation;
|
||||||
|
|
||||||
|
Deprecation::notification_version('3.0', 'silverstripe/fulltextsearch');
|
@ -21,19 +21,17 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.4 || ^8.0",
|
"php": "^7.3 || ^8.0",
|
||||||
"silverstripe/framework": "^4.10",
|
"silverstripe/framework": "^4.10",
|
||||||
"monolog/monolog": "~1.15",
|
"monolog/monolog": "~1.15",
|
||||||
"silverstripe/solr-php-client": "^1.0",
|
"ptcinc/solr-php-client": "^1.0",
|
||||||
"symfony/process": "^3.4 || ^4",
|
"symfony/process": "^3.2",
|
||||||
"tractorcow/silverstripe-proxy-db": "^1",
|
"tractorcow/silverstripe-proxy-db": "~0.1"
|
||||||
"ext-curl": "*"
|
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"silverstripe/cms": "^4.0",
|
"silverstripe/cms": "^4.0",
|
||||||
"phpunit/phpunit": "^9.5",
|
"phpunit/phpunit": "^9.5",
|
||||||
"squizlabs/php_codesniffer": "^3.0",
|
"squizlabs/php_codesniffer": "^3.0"
|
||||||
"symbiote/silverstripe-queuedjobs": "^4.9"
|
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
@ -16,9 +16,9 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
For more details about configurations options that may appear in
|
For more details about configurations options that may appear in
|
||||||
this file, see http://wiki.apache.org/solr/SolrConfigXml.
|
this file, see http://wiki.apache.org/solr/SolrConfigXml.
|
||||||
-->
|
-->
|
||||||
<config>
|
<config>
|
||||||
<!-- In all configuration below, a prefix of "solr." for class names
|
<!-- In all configuration below, a prefix of "solr." for class names
|
||||||
@ -46,19 +46,19 @@
|
|||||||
instanceDir.
|
instanceDir.
|
||||||
|
|
||||||
Please note that <lib/> directives are processed in the order
|
Please note that <lib/> directives are processed in the order
|
||||||
that they appear in your solrconfig.xml file, and are "stacked"
|
that they appear in your solrconfig.xml file, and are "stacked"
|
||||||
on top of each other when building a ClassLoader - so if you have
|
on top of each other when building a ClassLoader - so if you have
|
||||||
plugin jars with dependencies on other jars, the "lower level"
|
plugin jars with dependencies on other jars, the "lower level"
|
||||||
dependency jars should be loaded first.
|
dependency jars should be loaded first.
|
||||||
|
|
||||||
If a "./lib" directory exists in your instanceDir, all files
|
If a "./lib" directory exists in your instanceDir, all files
|
||||||
found in it are included as if you had used the following
|
found in it are included as if you had used the following
|
||||||
syntax...
|
syntax...
|
||||||
|
|
||||||
<lib dir="./lib" />
|
<lib dir="./lib" />
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- A 'dir' option by itself adds any files found in the directory
|
<!-- A 'dir' option by itself adds any files found in the directory
|
||||||
to the classpath, this is useful for including all jars in a
|
to the classpath, this is useful for including all jars in a
|
||||||
directory.
|
directory.
|
||||||
|
|
||||||
@ -69,11 +69,11 @@
|
|||||||
If a 'dir' option (with or without a regex) is used and nothing
|
If a 'dir' option (with or without a regex) is used and nothing
|
||||||
is found that matches, a warning will be logged.
|
is found that matches, a warning will be logged.
|
||||||
|
|
||||||
The examples below can be used to load some solr-contribs along
|
The examples below can be used to load some solr-contribs along
|
||||||
with their external dependencies.
|
with their external dependencies.
|
||||||
-->
|
-->
|
||||||
<lib dir="./lib" />
|
<lib dir="./lib" />
|
||||||
|
|
||||||
<lib dir="../../../contrib/extraction/lib" regex=".*\.jar" />
|
<lib dir="../../../contrib/extraction/lib" regex=".*\.jar" />
|
||||||
<lib dir="../../../dist/" regex="solr-cell-\d.*\.jar" />
|
<lib dir="../../../dist/" regex="solr-cell-\d.*\.jar" />
|
||||||
|
|
||||||
@ -86,14 +86,14 @@
|
|||||||
<lib dir="../../../contrib/velocity/lib" regex=".*\.jar" />
|
<lib dir="../../../contrib/velocity/lib" regex=".*\.jar" />
|
||||||
<lib dir="../../../dist/" regex="solr-velocity-\d.*\.jar" />
|
<lib dir="../../../dist/" regex="solr-velocity-\d.*\.jar" />
|
||||||
|
|
||||||
<!-- an exact 'path' can be used instead of a 'dir' to specify a
|
<!-- an exact 'path' can be used instead of a 'dir' to specify a
|
||||||
specific jar file. This will cause a serious error to be logged
|
specific jar file. This will cause a serious error to be logged
|
||||||
if it can't be loaded.
|
if it can't be loaded.
|
||||||
-->
|
-->
|
||||||
<!--
|
<!--
|
||||||
<lib path="../a-jar-that-does-not-exist.jar" />
|
<lib path="../a-jar-that-does-not-exist.jar" />
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- Data Directory
|
<!-- Data Directory
|
||||||
|
|
||||||
Used to specify an alternate directory to hold all index data
|
Used to specify an alternate directory to hold all index data
|
||||||
@ -105,7 +105,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<!-- The DirectoryFactory to use for indexes.
|
<!-- The DirectoryFactory to use for indexes.
|
||||||
|
|
||||||
solr.StandardDirectoryFactory is filesystem
|
solr.StandardDirectoryFactory is filesystem
|
||||||
based and tries to pick the best implementation for the current
|
based and tries to pick the best implementation for the current
|
||||||
JVM and platform. solr.NRTCachingDirectoryFactory, the default,
|
JVM and platform. solr.NRTCachingDirectoryFactory, the default,
|
||||||
@ -118,8 +118,8 @@
|
|||||||
solr.RAMDirectoryFactory is memory based, not
|
solr.RAMDirectoryFactory is memory based, not
|
||||||
persistent, and doesn't work with replication.
|
persistent, and doesn't work with replication.
|
||||||
-->
|
-->
|
||||||
<directoryFactory name="DirectoryFactory"
|
<directoryFactory name="DirectoryFactory"
|
||||||
class="${solr.directoryFactory:solr.NRTCachingDirectoryFactory}"/>
|
class="${solr.directoryFactory:solr.NRTCachingDirectoryFactory}"/>
|
||||||
|
|
||||||
<!-- The CodecFactory for defining the format of the inverted index.
|
<!-- The CodecFactory for defining the format of the inverted index.
|
||||||
The default implementation is SchemaCodecFactory, which is the official Lucene
|
The default implementation is SchemaCodecFactory, which is the official Lucene
|
||||||
@ -133,24 +133,24 @@
|
|||||||
<codecFactory class="solr.SchemaCodecFactory"/>
|
<codecFactory class="solr.SchemaCodecFactory"/>
|
||||||
|
|
||||||
<!-- To enable dynamic schema REST APIs, use the following for <schemaFactory>:
|
<!-- To enable dynamic schema REST APIs, use the following for <schemaFactory>:
|
||||||
|
|
||||||
<schemaFactory class="ManagedIndexSchemaFactory">
|
<schemaFactory class="ManagedIndexSchemaFactory">
|
||||||
<bool name="mutable">true</bool>
|
<bool name="mutable">true</bool>
|
||||||
<str name="managedSchemaResourceName">managed-schema</str>
|
<str name="managedSchemaResourceName">managed-schema</str>
|
||||||
</schemaFactory>
|
</schemaFactory>
|
||||||
|
|
||||||
When ManagedIndexSchemaFactory is specified, Solr will load the schema from
|
When ManagedIndexSchemaFactory is specified, Solr will load the schema from
|
||||||
he resource named in 'managedSchemaResourceName', rather than from schema.xml.
|
he resource named in 'managedSchemaResourceName', rather than from schema.xml.
|
||||||
Note that the managed schema resource CANNOT be named schema.xml. If the managed
|
Note that the managed schema resource CANNOT be named schema.xml. If the managed
|
||||||
schema does not exist, Solr will create it after reading schema.xml, then rename
|
schema does not exist, Solr will create it after reading schema.xml, then rename
|
||||||
'schema.xml' to 'schema.xml.bak'.
|
'schema.xml' to 'schema.xml.bak'.
|
||||||
|
|
||||||
Do NOT hand edit the managed schema - external modifications will be ignored and
|
Do NOT hand edit the managed schema - external modifications will be ignored and
|
||||||
overwritten as a result of schema modification REST API calls.
|
overwritten as a result of schema modification REST API calls.
|
||||||
|
|
||||||
When ManagedIndexSchemaFactory is specified with mutable = true, schema
|
When ManagedIndexSchemaFactory is specified with mutable = true, schema
|
||||||
modification REST API calls will be allowed; otherwise, error responses will be
|
modification REST API calls will be allowed; otherwise, error responses will be
|
||||||
sent back for these requests.
|
sent back for these requests.
|
||||||
-->
|
-->
|
||||||
<schemaFactory class="ClassicIndexSchemaFactory"/>
|
<schemaFactory class="ClassicIndexSchemaFactory"/>
|
||||||
|
|
||||||
@ -158,12 +158,12 @@
|
|||||||
Index Config - These settings control low-level behavior of indexing
|
Index Config - These settings control low-level behavior of indexing
|
||||||
Most example settings here show the default value, but are commented
|
Most example settings here show the default value, but are commented
|
||||||
out, to more easily see where customizations have been made.
|
out, to more easily see where customizations have been made.
|
||||||
|
|
||||||
Note: This replaces <indexDefaults> and <mainIndex> from older versions
|
Note: This replaces <indexDefaults> and <mainIndex> from older versions
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
|
||||||
<indexConfig>
|
<indexConfig>
|
||||||
<!-- maxFieldLength was removed in 4.0. To get similar behavior, include a
|
<!-- maxFieldLength was removed in 4.0. To get similar behavior, include a
|
||||||
LimitTokenCountFilterFactory in your fieldType definition. E.g.
|
LimitTokenCountFilterFactory in your fieldType definition. E.g.
|
||||||
<filter class="solr.LimitTokenCountFilterFactory" maxTokenCount="10000"/>
|
<filter class="solr.LimitTokenCountFilterFactory" maxTokenCount="10000"/>
|
||||||
-->
|
-->
|
||||||
<!-- Maximum time to wait for a write lock (ms) for an IndexWriter. Default: 1000 -->
|
<!-- Maximum time to wait for a write lock (ms) for an IndexWriter. Default: 1000 -->
|
||||||
@ -175,8 +175,8 @@
|
|||||||
Default in Solr/Lucene is 8. -->
|
Default in Solr/Lucene is 8. -->
|
||||||
<!-- <maxIndexingThreads>8</maxIndexingThreads> -->
|
<!-- <maxIndexingThreads>8</maxIndexingThreads> -->
|
||||||
|
|
||||||
<!-- Expert: Enabling compound file will use less files for the index,
|
<!-- Expert: Enabling compound file will use less files for the index,
|
||||||
using fewer file descriptors on the expense of performance decrease.
|
using fewer file descriptors on the expense of performance decrease.
|
||||||
Default in Lucene is "true". Default in Solr is "false" (since 3.6) -->
|
Default in Lucene is "true". Default in Solr is "false" (since 3.6) -->
|
||||||
<!-- <useCompoundFile>false</useCompoundFile> -->
|
<!-- <useCompoundFile>false</useCompoundFile> -->
|
||||||
|
|
||||||
@ -191,7 +191,7 @@
|
|||||||
<!-- <ramBufferSizeMB>100</ramBufferSizeMB> -->
|
<!-- <ramBufferSizeMB>100</ramBufferSizeMB> -->
|
||||||
<!-- <maxBufferedDocs>1000</maxBufferedDocs> -->
|
<!-- <maxBufferedDocs>1000</maxBufferedDocs> -->
|
||||||
|
|
||||||
<!-- Expert: Merge Policy
|
<!-- Expert: Merge Policy
|
||||||
The Merge Policy in Lucene controls how merging of segments is done.
|
The Merge Policy in Lucene controls how merging of segments is done.
|
||||||
The default since Solr/Lucene 3.3 is TieredMergePolicy.
|
The default since Solr/Lucene 3.3 is TieredMergePolicy.
|
||||||
The default since Lucene 2.3 was the LogByteSizeMergePolicy,
|
The default since Lucene 2.3 was the LogByteSizeMergePolicy,
|
||||||
@ -203,7 +203,7 @@
|
|||||||
<int name="segmentsPerTier">10</int>
|
<int name="segmentsPerTier">10</int>
|
||||||
</mergePolicy>
|
</mergePolicy>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- Merge Factor
|
<!-- Merge Factor
|
||||||
The merge factor controls how many segments will get merged at a time.
|
The merge factor controls how many segments will get merged at a time.
|
||||||
For TieredMergePolicy, mergeFactor is a convenience parameter which
|
For TieredMergePolicy, mergeFactor is a convenience parameter which
|
||||||
@ -212,7 +212,7 @@
|
|||||||
will be allowed before they are merged into one.
|
will be allowed before they are merged into one.
|
||||||
Default is 10 for both merge policies.
|
Default is 10 for both merge policies.
|
||||||
-->
|
-->
|
||||||
<!--
|
<!--
|
||||||
<mergeFactor>10</mergeFactor>
|
<mergeFactor>10</mergeFactor>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -222,15 +222,15 @@
|
|||||||
can perform merges in the background using separate threads.
|
can perform merges in the background using separate threads.
|
||||||
The SerialMergeScheduler (Lucene 2.2 default) does not.
|
The SerialMergeScheduler (Lucene 2.2 default) does not.
|
||||||
-->
|
-->
|
||||||
<!--
|
<!--
|
||||||
<mergeScheduler class="org.apache.lucene.index.ConcurrentMergeScheduler"/>
|
<mergeScheduler class="org.apache.lucene.index.ConcurrentMergeScheduler"/>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- LockFactory
|
<!-- LockFactory
|
||||||
|
|
||||||
This option specifies which Lucene LockFactory implementation
|
This option specifies which Lucene LockFactory implementation
|
||||||
to use.
|
to use.
|
||||||
|
|
||||||
single = SingleInstanceLockFactory - suggested for a
|
single = SingleInstanceLockFactory - suggested for a
|
||||||
read-only index or when there is no possibility of
|
read-only index or when there is no possibility of
|
||||||
another process trying to modify the index.
|
another process trying to modify the index.
|
||||||
@ -259,7 +259,7 @@
|
|||||||
<!--
|
<!--
|
||||||
<unlockOnStartup>false</unlockOnStartup>
|
<unlockOnStartup>false</unlockOnStartup>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- Expert: Controls how often Lucene loads terms into memory
|
<!-- Expert: Controls how often Lucene loads terms into memory
|
||||||
Default is 128 and is likely good for most everyone.
|
Default is 128 and is likely good for most everyone.
|
||||||
-->
|
-->
|
||||||
@ -268,7 +268,7 @@
|
|||||||
<!-- If true, IndexReaders will be reopened (often more efficient)
|
<!-- If true, IndexReaders will be reopened (often more efficient)
|
||||||
instead of closed and then opened. Default: true
|
instead of closed and then opened. Default: true
|
||||||
-->
|
-->
|
||||||
<!--
|
<!--
|
||||||
<reopenReaders>true</reopenReaders>
|
<reopenReaders>true</reopenReaders>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -279,11 +279,11 @@
|
|||||||
The default Solr IndexDeletionPolicy implementation supports
|
The default Solr IndexDeletionPolicy implementation supports
|
||||||
deleting index commit points on number of commits, age of
|
deleting index commit points on number of commits, age of
|
||||||
commit point and optimized status.
|
commit point and optimized status.
|
||||||
|
|
||||||
The latest commit point should always be preserved regardless
|
The latest commit point should always be preserved regardless
|
||||||
of the criteria.
|
of the criteria.
|
||||||
-->
|
-->
|
||||||
<!--
|
<!--
|
||||||
<deletionPolicy class="solr.SolrDeletionPolicy">
|
<deletionPolicy class="solr.SolrDeletionPolicy">
|
||||||
-->
|
-->
|
||||||
<!-- The number of commit points to be kept -->
|
<!-- The number of commit points to be kept -->
|
||||||
@ -298,12 +298,12 @@
|
|||||||
<str name="maxCommitAge">30MINUTES</str>
|
<str name="maxCommitAge">30MINUTES</str>
|
||||||
<str name="maxCommitAge">1DAY</str>
|
<str name="maxCommitAge">1DAY</str>
|
||||||
-->
|
-->
|
||||||
<!--
|
<!--
|
||||||
</deletionPolicy>
|
</deletionPolicy>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- Lucene Infostream
|
<!-- Lucene Infostream
|
||||||
|
|
||||||
To aid in advanced debugging, Lucene provides an "InfoStream"
|
To aid in advanced debugging, Lucene provides an "InfoStream"
|
||||||
of detailed information when indexing.
|
of detailed information when indexing.
|
||||||
|
|
||||||
@ -316,7 +316,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<!-- JMX
|
<!-- JMX
|
||||||
|
|
||||||
This example enables JMX if and only if an existing MBeanServer
|
This example enables JMX if and only if an existing MBeanServer
|
||||||
is found, use this if you want to configure JMX through JVM
|
is found, use this if you want to configure JMX through JVM
|
||||||
parameters. Remove this to disable exposing Solr configuration
|
parameters. Remove this to disable exposing Solr configuration
|
||||||
@ -326,7 +326,7 @@
|
|||||||
-->
|
-->
|
||||||
<jmx />
|
<jmx />
|
||||||
<!-- If you want to connect to a particular server, specify the
|
<!-- If you want to connect to a particular server, specify the
|
||||||
agentId
|
agentId
|
||||||
-->
|
-->
|
||||||
<!-- <jmx agentId="myAgent" /> -->
|
<!-- <jmx agentId="myAgent" /> -->
|
||||||
<!-- If you want to start a new MBeanServer, specify the serviceUrl -->
|
<!-- If you want to start a new MBeanServer, specify the serviceUrl -->
|
||||||
@ -341,16 +341,16 @@
|
|||||||
uncommitted changes to the index, so use of a hard autoCommit
|
uncommitted changes to the index, so use of a hard autoCommit
|
||||||
is recommended (see below).
|
is recommended (see below).
|
||||||
"dir" - the target directory for transaction logs, defaults to the
|
"dir" - the target directory for transaction logs, defaults to the
|
||||||
solr data directory. -->
|
solr data directory. -->
|
||||||
<updateLog>
|
<updateLog>
|
||||||
<str name="dir">${solr.ulog.dir:}</str>
|
<str name="dir">${solr.ulog.dir:}</str>
|
||||||
</updateLog>
|
</updateLog>
|
||||||
|
|
||||||
<!-- AutoCommit
|
<!-- AutoCommit
|
||||||
|
|
||||||
Perform a hard commit automatically under certain conditions.
|
Perform a hard commit automatically under certain conditions.
|
||||||
Instead of enabling autoCommit, consider using "commitWithin"
|
Instead of enabling autoCommit, consider using "commitWithin"
|
||||||
when adding documents.
|
when adding documents.
|
||||||
|
|
||||||
http://wiki.apache.org/solr/UpdateXmlMessages
|
http://wiki.apache.org/solr/UpdateXmlMessages
|
||||||
|
|
||||||
@ -359,7 +359,7 @@
|
|||||||
|
|
||||||
maxTime - Maximum amount of time in ms that is allowed to pass
|
maxTime - Maximum amount of time in ms that is allowed to pass
|
||||||
since a document was added before automatically
|
since a document was added before automatically
|
||||||
triggering a new commit.
|
triggering a new commit.
|
||||||
openSearcher - if false, the commit causes recent index changes
|
openSearcher - if false, the commit causes recent index changes
|
||||||
to be flushed to stable storage, but does not cause a new
|
to be flushed to stable storage, but does not cause a new
|
||||||
searcher to be opened to make those changes visible.
|
searcher to be opened to make those changes visible.
|
||||||
@ -367,9 +367,9 @@
|
|||||||
If the updateLog is enabled, then it's highly recommended to
|
If the updateLog is enabled, then it's highly recommended to
|
||||||
have some sort of hard autoCommit to limit the log size.
|
have some sort of hard autoCommit to limit the log size.
|
||||||
-->
|
-->
|
||||||
<autoCommit>
|
<autoCommit>
|
||||||
<maxTime>${solr.autoCommit.maxTime:15000}</maxTime>
|
<maxTime>${solr.autoCommit.maxTime:15000}</maxTime>
|
||||||
<openSearcher>false</openSearcher>
|
<openSearcher>false</openSearcher>
|
||||||
</autoCommit>
|
</autoCommit>
|
||||||
|
|
||||||
<!-- softAutoCommit is like autoCommit except it causes a
|
<!-- softAutoCommit is like autoCommit except it causes a
|
||||||
@ -378,12 +378,12 @@
|
|||||||
faster and more near-realtime friendly than a hard commit.
|
faster and more near-realtime friendly than a hard commit.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<autoSoftCommit>
|
<autoSoftCommit>
|
||||||
<maxTime>${solr.autoSoftCommit.maxTime:60000}</maxTime>
|
<maxTime>${solr.autoSoftCommit.maxTime:-1}</maxTime>
|
||||||
</autoSoftCommit>
|
</autoSoftCommit>
|
||||||
|
|
||||||
<!-- Update Related Event Listeners
|
<!-- Update Related Event Listeners
|
||||||
|
|
||||||
Various IndexWriter related events can trigger Listeners to
|
Various IndexWriter related events can trigger Listeners to
|
||||||
take actions.
|
take actions.
|
||||||
|
|
||||||
@ -392,10 +392,10 @@
|
|||||||
-->
|
-->
|
||||||
<!-- The RunExecutableListener executes an external command from a
|
<!-- The RunExecutableListener executes an external command from a
|
||||||
hook such as postCommit or postOptimize.
|
hook such as postCommit or postOptimize.
|
||||||
|
|
||||||
exe - the name of the executable to run
|
exe - the name of the executable to run
|
||||||
dir - dir to use as the current working directory. (default=".")
|
dir - dir to use as the current working directory. (default=".")
|
||||||
wait - the calling thread waits until the executable returns.
|
wait - the calling thread waits until the executable returns.
|
||||||
(default="true")
|
(default="true")
|
||||||
args - the arguments to pass to the program. (default is none)
|
args - the arguments to pass to the program. (default is none)
|
||||||
env - environment variables to set. (default is none)
|
env - environment variables to set. (default is none)
|
||||||
@ -415,7 +415,7 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
</updateHandler>
|
</updateHandler>
|
||||||
|
|
||||||
<!-- IndexReaderFactory
|
<!-- IndexReaderFactory
|
||||||
|
|
||||||
Use the following format to specify a custom IndexReaderFactory,
|
Use the following format to specify a custom IndexReaderFactory,
|
||||||
@ -447,7 +447,7 @@
|
|||||||
be specified.
|
be specified.
|
||||||
-->
|
-->
|
||||||
<!--
|
<!--
|
||||||
<indexReaderFactory name="IndexReaderFactory"
|
<indexReaderFactory name="IndexReaderFactory"
|
||||||
class="solr.StandardIndexReaderFactory">
|
class="solr.StandardIndexReaderFactory">
|
||||||
<int name="setTermIndexDivisor">12</int>
|
<int name="setTermIndexDivisor">12</int>
|
||||||
</indexReaderFactory >
|
</indexReaderFactory >
|
||||||
@ -463,12 +463,12 @@
|
|||||||
is thrown if exceeded.
|
is thrown if exceeded.
|
||||||
|
|
||||||
** WARNING **
|
** WARNING **
|
||||||
|
|
||||||
This option actually modifies a global Lucene property that
|
This option actually modifies a global Lucene property that
|
||||||
will affect all SolrCores. If multiple solrconfig.xml files
|
will affect all SolrCores. If multiple solrconfig.xml files
|
||||||
disagree on this property, the value at any given moment will
|
disagree on this property, the value at any given moment will
|
||||||
be based on the last SolrCore to be initialized.
|
be based on the last SolrCore to be initialized.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<maxBooleanClauses>1024</maxBooleanClauses>
|
<maxBooleanClauses>1024</maxBooleanClauses>
|
||||||
|
|
||||||
@ -477,7 +477,7 @@
|
|||||||
|
|
||||||
There are two implementations of cache available for Solr,
|
There are two implementations of cache available for Solr,
|
||||||
LRUCache, based on a synchronized LinkedHashMap, and
|
LRUCache, based on a synchronized LinkedHashMap, and
|
||||||
FastLRUCache, based on a ConcurrentHashMap.
|
FastLRUCache, based on a ConcurrentHashMap.
|
||||||
|
|
||||||
FastLRUCache has faster gets and slower puts in single
|
FastLRUCache has faster gets and slower puts in single
|
||||||
threaded operation and thus is generally faster than LRUCache
|
threaded operation and thus is generally faster than LRUCache
|
||||||
@ -502,7 +502,7 @@
|
|||||||
initialSize - the initial capacity (number of entries) of
|
initialSize - the initial capacity (number of entries) of
|
||||||
the cache. (see java.util.HashMap)
|
the cache. (see java.util.HashMap)
|
||||||
autowarmCount - the number of entries to prepopulate from
|
autowarmCount - the number of entries to prepopulate from
|
||||||
and old cache.
|
and old cache.
|
||||||
-->
|
-->
|
||||||
<filterCache class="solr.FastLRUCache"
|
<filterCache class="solr.FastLRUCache"
|
||||||
size="512"
|
size="512"
|
||||||
@ -510,28 +510,28 @@
|
|||||||
autowarmCount="0"/>
|
autowarmCount="0"/>
|
||||||
|
|
||||||
<!-- Query Result Cache
|
<!-- Query Result Cache
|
||||||
|
|
||||||
Caches results of searches - ordered lists of document ids
|
Caches results of searches - ordered lists of document ids
|
||||||
(DocList) based on a query, a sort, and the range of documents requested.
|
(DocList) based on a query, a sort, and the range of documents requested.
|
||||||
-->
|
-->
|
||||||
<queryResultCache class="solr.LRUCache"
|
<queryResultCache class="solr.LRUCache"
|
||||||
size="512"
|
size="512"
|
||||||
initialSize="512"
|
initialSize="512"
|
||||||
autowarmCount="0"/>
|
autowarmCount="0"/>
|
||||||
|
|
||||||
<!-- Document Cache
|
<!-- Document Cache
|
||||||
|
|
||||||
Caches Lucene Document objects (the stored fields for each
|
Caches Lucene Document objects (the stored fields for each
|
||||||
document). Since Lucene internal document ids are transient,
|
document). Since Lucene internal document ids are transient,
|
||||||
this cache will not be autowarmed.
|
this cache will not be autowarmed.
|
||||||
-->
|
-->
|
||||||
<documentCache class="solr.LRUCache"
|
<documentCache class="solr.LRUCache"
|
||||||
size="512"
|
size="512"
|
||||||
initialSize="512"
|
initialSize="512"
|
||||||
autowarmCount="0"/>
|
autowarmCount="0"/>
|
||||||
|
|
||||||
<!-- Field Value Cache
|
<!-- Field Value Cache
|
||||||
|
|
||||||
Cache used to hold field values that are quickly accessible
|
Cache used to hold field values that are quickly accessible
|
||||||
by document id. The fieldValueCache is created by default
|
by document id. The fieldValueCache is created by default
|
||||||
even if not configured here.
|
even if not configured here.
|
||||||
@ -549,8 +549,8 @@
|
|||||||
name through SolrIndexSearcher.getCache(),cacheLookup(), and
|
name through SolrIndexSearcher.getCache(),cacheLookup(), and
|
||||||
cacheInsert(). The purpose is to enable easy caching of
|
cacheInsert(). The purpose is to enable easy caching of
|
||||||
user/application level data. The regenerator argument should
|
user/application level data. The regenerator argument should
|
||||||
be specified as an implementation of solr.CacheRegenerator
|
be specified as an implementation of solr.CacheRegenerator
|
||||||
if autowarming is desired.
|
if autowarming is desired.
|
||||||
-->
|
-->
|
||||||
<!--
|
<!--
|
||||||
<cache name="myUserCache"
|
<cache name="myUserCache"
|
||||||
@ -597,12 +597,12 @@
|
|||||||
are collected. For example, if a search for a particular query
|
are collected. For example, if a search for a particular query
|
||||||
requests matching documents 10 through 19, and queryWindowSize is 50,
|
requests matching documents 10 through 19, and queryWindowSize is 50,
|
||||||
then documents 0 through 49 will be collected and cached. Any further
|
then documents 0 through 49 will be collected and cached. Any further
|
||||||
requests in that range can be satisfied via the cache.
|
requests in that range can be satisfied via the cache.
|
||||||
-->
|
-->
|
||||||
<queryResultWindowSize>20</queryResultWindowSize>
|
<queryResultWindowSize>20</queryResultWindowSize>
|
||||||
|
|
||||||
<!-- Maximum number of documents to cache for any entry in the
|
<!-- Maximum number of documents to cache for any entry in the
|
||||||
queryResultCache.
|
queryResultCache.
|
||||||
-->
|
-->
|
||||||
<queryResultMaxDocsCached>200</queryResultMaxDocsCached>
|
<queryResultMaxDocsCached>200</queryResultMaxDocsCached>
|
||||||
|
|
||||||
@ -620,10 +620,10 @@
|
|||||||
prepared but there is no current registered searcher to handle
|
prepared but there is no current registered searcher to handle
|
||||||
requests or to gain autowarming data from.
|
requests or to gain autowarming data from.
|
||||||
|
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<!-- QuerySenderListener takes an array of NamedList and executes a
|
<!-- QuerySenderListener takes an array of NamedList and executes a
|
||||||
local query request for each NamedList in sequence.
|
local query request for each NamedList in sequence.
|
||||||
-->
|
-->
|
||||||
<listener event="newSearcher" class="solr.QuerySenderListener">
|
<listener event="newSearcher" class="solr.QuerySenderListener">
|
||||||
<arr name="queries">
|
<arr name="queries">
|
||||||
@ -651,7 +651,7 @@
|
|||||||
<useColdSearcher>false</useColdSearcher>
|
<useColdSearcher>false</useColdSearcher>
|
||||||
|
|
||||||
<!-- Max Warming Searchers
|
<!-- Max Warming Searchers
|
||||||
|
|
||||||
Maximum number of searchers that may be warming in the
|
Maximum number of searchers that may be warming in the
|
||||||
background concurrently. An error is returned if this limit
|
background concurrently. An error is returned if this limit
|
||||||
is exceeded.
|
is exceeded.
|
||||||
@ -673,7 +673,7 @@
|
|||||||
such as /select?qt=XXX
|
such as /select?qt=XXX
|
||||||
|
|
||||||
handleSelect="true" will cause the SolrDispatchFilter to process
|
handleSelect="true" will cause the SolrDispatchFilter to process
|
||||||
the request and dispatch the query to a handler specified by the
|
the request and dispatch the query to a handler specified by the
|
||||||
"qt" param, assuming "/select" isn't already registered.
|
"qt" param, assuming "/select" isn't already registered.
|
||||||
|
|
||||||
handleSelect="false" will cause the SolrDispatchFilter to
|
handleSelect="false" will cause the SolrDispatchFilter to
|
||||||
@ -695,26 +695,26 @@
|
|||||||
|
|
||||||
multipartUploadLimitInKB - specifies the max size (in KiB) of
|
multipartUploadLimitInKB - specifies the max size (in KiB) of
|
||||||
Multipart File Uploads that Solr will allow in a Request.
|
Multipart File Uploads that Solr will allow in a Request.
|
||||||
|
|
||||||
formdataUploadLimitInKB - specifies the max size (in KiB) of
|
formdataUploadLimitInKB - specifies the max size (in KiB) of
|
||||||
form data (application/x-www-form-urlencoded) sent via
|
form data (application/x-www-form-urlencoded) sent via
|
||||||
POST. You can use POST to pass request parameters not
|
POST. You can use POST to pass request parameters not
|
||||||
fitting into the URL.
|
fitting into the URL.
|
||||||
|
|
||||||
addHttpRequestToContext - if set to true, it will instruct
|
addHttpRequestToContext - if set to true, it will instruct
|
||||||
the requestParsers to include the original HttpServletRequest
|
the requestParsers to include the original HttpServletRequest
|
||||||
object in the context map of the SolrQueryRequest under the
|
object in the context map of the SolrQueryRequest under the
|
||||||
key "httpRequest". It will not be used by any of the existing
|
key "httpRequest". It will not be used by any of the existing
|
||||||
Solr components, but may be useful when developing custom
|
Solr components, but may be useful when developing custom
|
||||||
plugins.
|
plugins.
|
||||||
|
|
||||||
*** WARNING ***
|
*** WARNING ***
|
||||||
The settings below authorize Solr to fetch remote files, You
|
The settings below authorize Solr to fetch remote files, You
|
||||||
should make sure your system has some authentication before
|
should make sure your system has some authentication before
|
||||||
using enableRemoteStreaming="true"
|
using enableRemoteStreaming="true"
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<requestParsers enableRemoteStreaming="true"
|
<requestParsers enableRemoteStreaming="true"
|
||||||
multipartUploadLimitInKB="2048000"
|
multipartUploadLimitInKB="2048000"
|
||||||
formdataUploadLimitInKB="2048"
|
formdataUploadLimitInKB="2048"
|
||||||
addHttpRequestToContext="false"/>
|
addHttpRequestToContext="false"/>
|
||||||
@ -730,21 +730,21 @@
|
|||||||
<!-- If you include a <cacheControl> directive, it will be used to
|
<!-- If you include a <cacheControl> directive, it will be used to
|
||||||
generate a Cache-Control header (as well as an Expires header
|
generate a Cache-Control header (as well as an Expires header
|
||||||
if the value contains "max-age=")
|
if the value contains "max-age=")
|
||||||
|
|
||||||
By default, no Cache-Control header is generated.
|
By default, no Cache-Control header is generated.
|
||||||
|
|
||||||
You can use the <cacheControl> option even if you have set
|
You can use the <cacheControl> option even if you have set
|
||||||
never304="true"
|
never304="true"
|
||||||
-->
|
-->
|
||||||
<!--
|
<!--
|
||||||
<httpCaching never304="true" >
|
<httpCaching never304="true" >
|
||||||
<cacheControl>max-age=30, public</cacheControl>
|
<cacheControl>max-age=30, public</cacheControl>
|
||||||
</httpCaching>
|
</httpCaching>
|
||||||
-->
|
-->
|
||||||
<!-- To enable Solr to respond with automatically generated HTTP
|
<!-- To enable Solr to respond with automatically generated HTTP
|
||||||
Caching headers, and to response to Cache Validation requests
|
Caching headers, and to response to Cache Validation requests
|
||||||
correctly, set the value of never304="false"
|
correctly, set the value of never304="false"
|
||||||
|
|
||||||
This will cause Solr to generate Last-Modified and ETag
|
This will cause Solr to generate Last-Modified and ETag
|
||||||
headers based on the properties of the Index.
|
headers based on the properties of the Index.
|
||||||
|
|
||||||
@ -769,12 +769,12 @@
|
|||||||
<!--
|
<!--
|
||||||
<httpCaching lastModifiedFrom="openTime"
|
<httpCaching lastModifiedFrom="openTime"
|
||||||
etagSeed="Solr">
|
etagSeed="Solr">
|
||||||
<cacheControl>max-age=30, public</cacheControl>
|
<cacheControl>max-age=30, public</cacheControl>
|
||||||
</httpCaching>
|
</httpCaching>
|
||||||
-->
|
-->
|
||||||
</requestDispatcher>
|
</requestDispatcher>
|
||||||
|
|
||||||
<!-- Request Handlers
|
<!-- Request Handlers
|
||||||
|
|
||||||
http://wiki.apache.org/solr/SolrRequestHandler
|
http://wiki.apache.org/solr/SolrRequestHandler
|
||||||
|
|
||||||
@ -863,7 +863,7 @@
|
|||||||
<str>nameOfCustomComponent2</str>
|
<str>nameOfCustomComponent2</str>
|
||||||
</arr>
|
</arr>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<arr name="last-components">
|
<arr name="last-components">
|
||||||
<str>spellcheck</str>
|
<str>spellcheck</str>
|
||||||
</arr>
|
</arr>
|
||||||
@ -990,8 +990,8 @@
|
|||||||
</requestHandler>
|
</requestHandler>
|
||||||
|
|
||||||
|
|
||||||
<!-- Update Request Handler.
|
<!-- Update Request Handler.
|
||||||
|
|
||||||
http://wiki.apache.org/solr/UpdateXmlMessages
|
http://wiki.apache.org/solr/UpdateXmlMessages
|
||||||
|
|
||||||
The canonical Request Handler for Modifying the Index through
|
The canonical Request Handler for Modifying the Index through
|
||||||
@ -1000,11 +1000,11 @@
|
|||||||
Note: Since solr1.1 requestHandlers requires a valid content
|
Note: Since solr1.1 requestHandlers requires a valid content
|
||||||
type header if posted in the body. For example, curl now
|
type header if posted in the body. For example, curl now
|
||||||
requires: -H 'Content-type:text/xml; charset=utf-8'
|
requires: -H 'Content-type:text/xml; charset=utf-8'
|
||||||
|
|
||||||
To override the request content type and force a specific
|
To override the request content type and force a specific
|
||||||
Content-type, use the request parameter:
|
Content-type, use the request parameter:
|
||||||
?update.contentType=text/csv
|
?update.contentType=text/csv
|
||||||
|
|
||||||
This handler will pick a response format to match the input
|
This handler will pick a response format to match the input
|
||||||
if the 'wt' parameter is not explicit
|
if the 'wt' parameter is not explicit
|
||||||
-->
|
-->
|
||||||
@ -1034,10 +1034,10 @@
|
|||||||
|
|
||||||
<!-- Solr Cell Update Request Handler
|
<!-- Solr Cell Update Request Handler
|
||||||
|
|
||||||
http://wiki.apache.org/solr/ExtractingRequestHandler
|
http://wiki.apache.org/solr/ExtractingRequestHandler
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<requestHandler name="/update/extract"
|
<requestHandler name="/update/extract"
|
||||||
startup="lazy"
|
startup="lazy"
|
||||||
class="solr.extraction.ExtractingRequestHandler" >
|
class="solr.extraction.ExtractingRequestHandler" >
|
||||||
<lst name="defaults">
|
<lst name="defaults">
|
||||||
@ -1070,7 +1070,7 @@
|
|||||||
field value analysis will be marked as "matched" for every
|
field value analysis will be marked as "matched" for every
|
||||||
token that is produces by the query analysis
|
token that is produces by the query analysis
|
||||||
-->
|
-->
|
||||||
<requestHandler name="/analysis/field"
|
<requestHandler name="/analysis/field"
|
||||||
startup="lazy"
|
startup="lazy"
|
||||||
class="solr.FieldAnalysisRequestHandler" />
|
class="solr.FieldAnalysisRequestHandler" />
|
||||||
|
|
||||||
@ -1103,18 +1103,18 @@
|
|||||||
request parameter that holds the query text to be analyzed. It
|
request parameter that holds the query text to be analyzed. It
|
||||||
also supports the "analysis.showmatch" parameter which when set to
|
also supports the "analysis.showmatch" parameter which when set to
|
||||||
true, all field tokens that match the query tokens will be marked
|
true, all field tokens that match the query tokens will be marked
|
||||||
as a "match".
|
as a "match".
|
||||||
-->
|
-->
|
||||||
<requestHandler name="/analysis/document"
|
<requestHandler name="/analysis/document"
|
||||||
class="solr.DocumentAnalysisRequestHandler"
|
class="solr.DocumentAnalysisRequestHandler"
|
||||||
startup="lazy" />
|
startup="lazy" />
|
||||||
|
|
||||||
<!-- Admin Handlers
|
<!-- Admin Handlers
|
||||||
|
|
||||||
Admin Handlers - This will register all the standard admin
|
Admin Handlers - This will register all the standard admin
|
||||||
RequestHandlers.
|
RequestHandlers.
|
||||||
-->
|
-->
|
||||||
<requestHandler name="/admin/"
|
<requestHandler name="/admin/"
|
||||||
class="solr.admin.AdminHandlers" />
|
class="solr.admin.AdminHandlers" />
|
||||||
<!-- This single handler is equivalent to the following... -->
|
<!-- This single handler is equivalent to the following... -->
|
||||||
<!--
|
<!--
|
||||||
@ -1126,14 +1126,14 @@
|
|||||||
<requestHandler name="/admin/file" class="solr.admin.ShowFileRequestHandler" >
|
<requestHandler name="/admin/file" class="solr.admin.ShowFileRequestHandler" >
|
||||||
-->
|
-->
|
||||||
<!-- If you wish to hide files under ${solr.home}/conf, explicitly
|
<!-- If you wish to hide files under ${solr.home}/conf, explicitly
|
||||||
register the ShowFileRequestHandler using:
|
register the ShowFileRequestHandler using:
|
||||||
-->
|
-->
|
||||||
<!--
|
<!--
|
||||||
<requestHandler name="/admin/file"
|
<requestHandler name="/admin/file"
|
||||||
class="solr.admin.ShowFileRequestHandler" >
|
class="solr.admin.ShowFileRequestHandler" >
|
||||||
<lst name="invariants">
|
<lst name="invariants">
|
||||||
<str name="hidden">synonyms.txt</str>
|
<str name="hidden">synonyms.txt</str>
|
||||||
<str name="hidden">anotherfile.txt</str>
|
<str name="hidden">anotherfile.txt</str>
|
||||||
</lst>
|
</lst>
|
||||||
</requestHandler>
|
</requestHandler>
|
||||||
-->
|
-->
|
||||||
@ -1146,10 +1146,10 @@
|
|||||||
<lst name="defaults">
|
<lst name="defaults">
|
||||||
<str name="echoParams">all</str>
|
<str name="echoParams">all</str>
|
||||||
</lst>
|
</lst>
|
||||||
<!-- An optional feature of the PingRequestHandler is to configure the
|
<!-- An optional feature of the PingRequestHandler is to configure the
|
||||||
handler with a "healthcheckFile" which can be used to enable/disable
|
handler with a "healthcheckFile" which can be used to enable/disable
|
||||||
the PingRequestHandler.
|
the PingRequestHandler.
|
||||||
relative paths are resolved against the data dir
|
relative paths are resolved against the data dir
|
||||||
-->
|
-->
|
||||||
<!-- <str name="healthcheckFile">server-enabled.txt</str> -->
|
<!-- <str name="healthcheckFile">server-enabled.txt</str> -->
|
||||||
</requestHandler>
|
</requestHandler>
|
||||||
@ -1157,29 +1157,29 @@
|
|||||||
<!-- Echo the request contents back to the client -->
|
<!-- Echo the request contents back to the client -->
|
||||||
<requestHandler name="/debug/dump" class="solr.DumpRequestHandler" >
|
<requestHandler name="/debug/dump" class="solr.DumpRequestHandler" >
|
||||||
<lst name="defaults">
|
<lst name="defaults">
|
||||||
<str name="echoParams">explicit</str>
|
<str name="echoParams">explicit</str>
|
||||||
<str name="echoHandler">true</str>
|
<str name="echoHandler">true</str>
|
||||||
</lst>
|
</lst>
|
||||||
</requestHandler>
|
</requestHandler>
|
||||||
|
|
||||||
<!-- Solr Replication
|
<!-- Solr Replication
|
||||||
|
|
||||||
The SolrReplicationHandler supports replicating indexes from a
|
The SolrReplicationHandler supports replicating indexes from a
|
||||||
"master" used for indexing and "slaves" used for queries.
|
"master" used for indexing and "slaves" used for queries.
|
||||||
|
|
||||||
http://wiki.apache.org/solr/SolrReplication
|
http://wiki.apache.org/solr/SolrReplication
|
||||||
|
|
||||||
It is also necessary for SolrCloud to function (in Cloud mode, the
|
It is also necessary for SolrCloud to function (in Cloud mode, the
|
||||||
replication handler is used to bulk transfer segments when nodes
|
replication handler is used to bulk transfer segments when nodes
|
||||||
are added or need to recover).
|
are added or need to recover).
|
||||||
|
|
||||||
https://wiki.apache.org/solr/SolrCloud/
|
https://wiki.apache.org/solr/SolrCloud/
|
||||||
-->
|
-->
|
||||||
<requestHandler name="/replication" class="solr.ReplicationHandler" >
|
<requestHandler name="/replication" class="solr.ReplicationHandler" >
|
||||||
<!--
|
<!--
|
||||||
To enable simple master/slave replication, uncomment one of the
|
To enable simple master/slave replication, uncomment one of the
|
||||||
sections below, depending on whether this solr instance should be
|
sections below, depending on whether this solr instance should be
|
||||||
the "master" or a "slave". If this instance is a "slave" you will
|
the "master" or a "slave". If this instance is a "slave" you will
|
||||||
also need to fill in the masterUrl to point to a real machine.
|
also need to fill in the masterUrl to point to a real machine.
|
||||||
-->
|
-->
|
||||||
<!--
|
<!--
|
||||||
@ -1199,18 +1199,18 @@
|
|||||||
|
|
||||||
<!-- Search Components
|
<!-- Search Components
|
||||||
|
|
||||||
Search components are registered to SolrCore and used by
|
Search components are registered to SolrCore and used by
|
||||||
instances of SearchHandler (which can access them by name)
|
instances of SearchHandler (which can access them by name)
|
||||||
|
|
||||||
By default, the following components are available:
|
By default, the following components are available:
|
||||||
|
|
||||||
<searchComponent name="query" class="solr.QueryComponent" />
|
<searchComponent name="query" class="solr.QueryComponent" />
|
||||||
<searchComponent name="facet" class="solr.FacetComponent" />
|
<searchComponent name="facet" class="solr.FacetComponent" />
|
||||||
<searchComponent name="mlt" class="solr.MoreLikeThisComponent" />
|
<searchComponent name="mlt" class="solr.MoreLikeThisComponent" />
|
||||||
<searchComponent name="highlight" class="solr.HighlightComponent" />
|
<searchComponent name="highlight" class="solr.HighlightComponent" />
|
||||||
<searchComponent name="stats" class="solr.StatsComponent" />
|
<searchComponent name="stats" class="solr.StatsComponent" />
|
||||||
<searchComponent name="debug" class="solr.DebugComponent" />
|
<searchComponent name="debug" class="solr.DebugComponent" />
|
||||||
|
|
||||||
Default configuration in a requestHandler would look like:
|
Default configuration in a requestHandler would look like:
|
||||||
|
|
||||||
<arr name="components">
|
<arr name="components">
|
||||||
@ -1222,28 +1222,28 @@
|
|||||||
<str>debug</str>
|
<str>debug</str>
|
||||||
</arr>
|
</arr>
|
||||||
|
|
||||||
If you register a searchComponent to one of the standard names,
|
If you register a searchComponent to one of the standard names,
|
||||||
that will be used instead of the default.
|
that will be used instead of the default.
|
||||||
|
|
||||||
To insert components before or after the 'standard' components, use:
|
To insert components before or after the 'standard' components, use:
|
||||||
|
|
||||||
<arr name="first-components">
|
<arr name="first-components">
|
||||||
<str>myFirstComponentName</str>
|
<str>myFirstComponentName</str>
|
||||||
</arr>
|
</arr>
|
||||||
|
|
||||||
<arr name="last-components">
|
<arr name="last-components">
|
||||||
<str>myLastComponentName</str>
|
<str>myLastComponentName</str>
|
||||||
</arr>
|
</arr>
|
||||||
|
|
||||||
NOTE: The component registered with the name "debug" will
|
NOTE: The component registered with the name "debug" will
|
||||||
always be executed after the "last-components"
|
always be executed after the "last-components"
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- Spell Check
|
<!-- Spell Check
|
||||||
|
|
||||||
The spell check component can return a list of alternative spelling
|
The spell check component can return a list of alternative spelling
|
||||||
suggestions.
|
suggestions.
|
||||||
|
|
||||||
http://wiki.apache.org/solr/SpellCheckComponent
|
http://wiki.apache.org/solr/SpellCheckComponent
|
||||||
-->
|
-->
|
||||||
@ -1302,11 +1302,11 @@
|
|||||||
<float name="thresholdTokenFrequency">.01</float>
|
<float name="thresholdTokenFrequency">.01</float>
|
||||||
-->
|
-->
|
||||||
</lst>
|
</lst>
|
||||||
|
|
||||||
<!-- a spellchecker that can break or combine words. See "/spell" handler below for usage -->
|
<!-- a spellchecker that can break or combine words. See "/spell" handler below for usage -->
|
||||||
<lst name="spellchecker">
|
<lst name="spellchecker">
|
||||||
<str name="name">wordbreak</str>
|
<str name="name">wordbreak</str>
|
||||||
<str name="classname">solr.WordBreakSolrSpellChecker</str>
|
<str name="classname">solr.WordBreakSolrSpellChecker</str>
|
||||||
<str name="field">_text</str>
|
<str name="field">_text</str>
|
||||||
<str name="combineWords">true</str>
|
<str name="combineWords">true</str>
|
||||||
<str name="breakWords">true</str>
|
<str name="breakWords">true</str>
|
||||||
@ -1325,7 +1325,7 @@
|
|||||||
</lst>
|
</lst>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- a spellchecker that use an alternate comparator
|
<!-- a spellchecker that use an alternate comparator
|
||||||
|
|
||||||
comparatorClass be one of:
|
comparatorClass be one of:
|
||||||
1. score (default)
|
1. score (default)
|
||||||
@ -1352,7 +1352,7 @@
|
|||||||
-->
|
-->
|
||||||
</searchComponent>
|
</searchComponent>
|
||||||
|
|
||||||
<!-- A request handler for demonstrating the spellcheck component.
|
<!-- A request handler for demonstrating the spellcheck component.
|
||||||
|
|
||||||
NOTE: This is purely as an example. The whole purpose of the
|
NOTE: This is purely as an example. The whole purpose of the
|
||||||
SpellCheckComponent is to hook it into the request handler that
|
SpellCheckComponent is to hook it into the request handler that
|
||||||
@ -1361,7 +1361,7 @@
|
|||||||
|
|
||||||
IN OTHER WORDS, THERE IS REALLY GOOD CHANCE THE SETUP BELOW IS
|
IN OTHER WORDS, THERE IS REALLY GOOD CHANCE THE SETUP BELOW IS
|
||||||
NOT WHAT YOU WANT FOR YOUR PRODUCTION SYSTEM!
|
NOT WHAT YOU WANT FOR YOUR PRODUCTION SYSTEM!
|
||||||
|
|
||||||
See http://wiki.apache.org/solr/SpellCheckComponent for details
|
See http://wiki.apache.org/solr/SpellCheckComponent for details
|
||||||
on the request parameters.
|
on the request parameters.
|
||||||
-->
|
-->
|
||||||
@ -1375,14 +1375,14 @@
|
|||||||
<str name="spellcheck.dictionary">default</str>
|
<str name="spellcheck.dictionary">default</str>
|
||||||
<str name="spellcheck.dictionary">wordbreak</str>
|
<str name="spellcheck.dictionary">wordbreak</str>
|
||||||
<str name="spellcheck">on</str>
|
<str name="spellcheck">on</str>
|
||||||
<str name="spellcheck.extendedResults">true</str>
|
<str name="spellcheck.extendedResults">true</str>
|
||||||
<str name="spellcheck.count">10</str>
|
<str name="spellcheck.count">10</str>
|
||||||
<str name="spellcheck.alternativeTermCount">5</str>
|
<str name="spellcheck.alternativeTermCount">5</str>
|
||||||
<str name="spellcheck.maxResultsForSuggest">5</str>
|
<str name="spellcheck.maxResultsForSuggest">5</str>
|
||||||
<str name="spellcheck.collate">true</str>
|
<str name="spellcheck.collate">true</str>
|
||||||
<str name="spellcheck.collateExtendedResults">true</str>
|
<str name="spellcheck.collateExtendedResults">true</str>
|
||||||
<str name="spellcheck.maxCollationTries">10</str>
|
<str name="spellcheck.maxCollationTries">10</str>
|
||||||
<str name="spellcheck.maxCollations">5</str>
|
<str name="spellcheck.maxCollations">5</str>
|
||||||
</lst>
|
</lst>
|
||||||
<arr name="last-components">
|
<arr name="last-components">
|
||||||
<str>spellcheck</str>
|
<str>spellcheck</str>
|
||||||
@ -1399,8 +1399,8 @@
|
|||||||
|
|
||||||
This is purely as an example.
|
This is purely as an example.
|
||||||
|
|
||||||
In reality you will likely want to add the component to your
|
In reality you will likely want to add the component to your
|
||||||
already specified request handlers.
|
already specified request handlers.
|
||||||
-->
|
-->
|
||||||
<requestHandler name="/tvrh" class="solr.SearchHandler" startup="lazy">
|
<requestHandler name="/tvrh" class="solr.SearchHandler" startup="lazy">
|
||||||
<lst name="defaults">
|
<lst name="defaults">
|
||||||
@ -1433,11 +1433,11 @@
|
|||||||
<!-- Class name of Carrot2 clustering algorithm.
|
<!-- Class name of Carrot2 clustering algorithm.
|
||||||
|
|
||||||
Currently available algorithms are:
|
Currently available algorithms are:
|
||||||
|
|
||||||
* org.carrot2.clustering.lingo.LingoClusteringAlgorithm
|
* org.carrot2.clustering.lingo.LingoClusteringAlgorithm
|
||||||
* org.carrot2.clustering.stc.STCClusteringAlgorithm
|
* org.carrot2.clustering.stc.STCClusteringAlgorithm
|
||||||
* org.carrot2.clustering.kmeans.BisectingKMeansClusteringAlgorithm
|
* org.carrot2.clustering.kmeans.BisectingKMeansClusteringAlgorithm
|
||||||
|
|
||||||
See http://project.carrot2.org/algorithms.html for the
|
See http://project.carrot2.org/algorithms.html for the
|
||||||
algorithm's characteristics.
|
algorithm's characteristics.
|
||||||
-->
|
-->
|
||||||
@ -1484,8 +1484,8 @@
|
|||||||
|
|
||||||
This is purely as an example.
|
This is purely as an example.
|
||||||
|
|
||||||
In reality you will likely want to add the component to your
|
In reality you will likely want to add the component to your
|
||||||
already specified request handlers.
|
already specified request handlers.
|
||||||
-->
|
-->
|
||||||
<requestHandler name="/clustering"
|
<requestHandler name="/clustering"
|
||||||
startup="lazy"
|
startup="lazy"
|
||||||
@ -1506,7 +1506,7 @@
|
|||||||
<!--<int name="carrot.numDescriptions">5</int>-->
|
<!--<int name="carrot.numDescriptions">5</int>-->
|
||||||
<!-- produce sub clusters -->
|
<!-- produce sub clusters -->
|
||||||
<bool name="carrot.outputSubClusters">false</bool>
|
<bool name="carrot.outputSubClusters">false</bool>
|
||||||
|
|
||||||
<str name="defType">edismax</str>
|
<str name="defType">edismax</str>
|
||||||
<str name="qf">
|
<str name="qf">
|
||||||
text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4
|
text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4
|
||||||
@ -1514,12 +1514,12 @@
|
|||||||
<str name="q.alt">*:*</str>
|
<str name="q.alt">*:*</str>
|
||||||
<str name="rows">10</str>
|
<str name="rows">10</str>
|
||||||
<str name="fl">*,score</str>
|
<str name="fl">*,score</str>
|
||||||
</lst>
|
</lst>
|
||||||
<arr name="last-components">
|
<arr name="last-components">
|
||||||
<str>clustering</str>
|
<str>clustering</str>
|
||||||
</arr>
|
</arr>
|
||||||
</requestHandler>
|
</requestHandler>
|
||||||
|
|
||||||
<!-- Terms Component
|
<!-- Terms Component
|
||||||
|
|
||||||
http://wiki.apache.org/solr/TermsComponent
|
http://wiki.apache.org/solr/TermsComponent
|
||||||
@ -1534,7 +1534,7 @@
|
|||||||
<lst name="defaults">
|
<lst name="defaults">
|
||||||
<bool name="terms">true</bool>
|
<bool name="terms">true</bool>
|
||||||
<bool name="distrib">false</bool>
|
<bool name="distrib">false</bool>
|
||||||
</lst>
|
</lst>
|
||||||
<arr name="components">
|
<arr name="components">
|
||||||
<str>terms</str>
|
<str>terms</str>
|
||||||
</arr>
|
</arr>
|
||||||
@ -1574,7 +1574,7 @@
|
|||||||
<highlighting>
|
<highlighting>
|
||||||
<!-- Configure the standard fragmenter -->
|
<!-- Configure the standard fragmenter -->
|
||||||
<!-- This could most likely be commented out in the "default" case -->
|
<!-- This could most likely be commented out in the "default" case -->
|
||||||
<fragmenter name="gap"
|
<fragmenter name="gap"
|
||||||
default="true"
|
default="true"
|
||||||
class="solr.highlight.GapFragmenter">
|
class="solr.highlight.GapFragmenter">
|
||||||
<lst name="defaults">
|
<lst name="defaults">
|
||||||
@ -1582,10 +1582,10 @@
|
|||||||
</lst>
|
</lst>
|
||||||
</fragmenter>
|
</fragmenter>
|
||||||
|
|
||||||
<!-- A regular-expression-based fragmenter
|
<!-- A regular-expression-based fragmenter
|
||||||
(for sentence extraction)
|
(for sentence extraction)
|
||||||
-->
|
-->
|
||||||
<fragmenter name="regex"
|
<fragmenter name="regex"
|
||||||
class="solr.highlight.RegexFragmenter">
|
class="solr.highlight.RegexFragmenter">
|
||||||
<lst name="defaults">
|
<lst name="defaults">
|
||||||
<!-- slightly smaller fragsizes work better because of slop -->
|
<!-- slightly smaller fragsizes work better because of slop -->
|
||||||
@ -1598,7 +1598,7 @@
|
|||||||
</fragmenter>
|
</fragmenter>
|
||||||
|
|
||||||
<!-- Configure the standard formatter -->
|
<!-- Configure the standard formatter -->
|
||||||
<formatter name="html"
|
<formatter name="html"
|
||||||
default="true"
|
default="true"
|
||||||
class="solr.highlight.HtmlFormatter">
|
class="solr.highlight.HtmlFormatter">
|
||||||
<lst name="defaults">
|
<lst name="defaults">
|
||||||
@ -1608,27 +1608,27 @@
|
|||||||
</formatter>
|
</formatter>
|
||||||
|
|
||||||
<!-- Configure the standard encoder -->
|
<!-- Configure the standard encoder -->
|
||||||
<encoder name="html"
|
<encoder name="html"
|
||||||
class="solr.highlight.HtmlEncoder" />
|
class="solr.highlight.HtmlEncoder" />
|
||||||
|
|
||||||
<!-- Configure the standard fragListBuilder -->
|
<!-- Configure the standard fragListBuilder -->
|
||||||
<fragListBuilder name="simple"
|
<fragListBuilder name="simple"
|
||||||
class="solr.highlight.SimpleFragListBuilder"/>
|
class="solr.highlight.SimpleFragListBuilder"/>
|
||||||
|
|
||||||
<!-- Configure the single fragListBuilder -->
|
<!-- Configure the single fragListBuilder -->
|
||||||
<fragListBuilder name="single"
|
<fragListBuilder name="single"
|
||||||
class="solr.highlight.SingleFragListBuilder"/>
|
class="solr.highlight.SingleFragListBuilder"/>
|
||||||
|
|
||||||
<!-- Configure the weighted fragListBuilder -->
|
<!-- Configure the weighted fragListBuilder -->
|
||||||
<fragListBuilder name="weighted"
|
<fragListBuilder name="weighted"
|
||||||
default="true"
|
default="true"
|
||||||
class="solr.highlight.WeightedFragListBuilder"/>
|
class="solr.highlight.WeightedFragListBuilder"/>
|
||||||
|
|
||||||
<!-- default tag FragmentsBuilder -->
|
<!-- default tag FragmentsBuilder -->
|
||||||
<fragmentsBuilder name="default"
|
<fragmentsBuilder name="default"
|
||||||
default="true"
|
default="true"
|
||||||
class="solr.highlight.ScoreOrderFragmentsBuilder">
|
class="solr.highlight.ScoreOrderFragmentsBuilder">
|
||||||
<!--
|
<!--
|
||||||
<lst name="defaults">
|
<lst name="defaults">
|
||||||
<str name="hl.multiValuedSeparatorChar">/</str>
|
<str name="hl.multiValuedSeparatorChar">/</str>
|
||||||
</lst>
|
</lst>
|
||||||
@ -1636,7 +1636,7 @@
|
|||||||
</fragmentsBuilder>
|
</fragmentsBuilder>
|
||||||
|
|
||||||
<!-- multi-colored tag FragmentsBuilder -->
|
<!-- multi-colored tag FragmentsBuilder -->
|
||||||
<fragmentsBuilder name="colored"
|
<fragmentsBuilder name="colored"
|
||||||
class="solr.highlight.ScoreOrderFragmentsBuilder">
|
class="solr.highlight.ScoreOrderFragmentsBuilder">
|
||||||
<lst name="defaults">
|
<lst name="defaults">
|
||||||
<str name="hl.tag.pre"><![CDATA[
|
<str name="hl.tag.pre"><![CDATA[
|
||||||
@ -1648,8 +1648,8 @@
|
|||||||
<str name="hl.tag.post"><![CDATA[</b>]]></str>
|
<str name="hl.tag.post"><![CDATA[</b>]]></str>
|
||||||
</lst>
|
</lst>
|
||||||
</fragmentsBuilder>
|
</fragmentsBuilder>
|
||||||
|
|
||||||
<boundaryScanner name="default"
|
<boundaryScanner name="default"
|
||||||
default="true"
|
default="true"
|
||||||
class="solr.highlight.SimpleBoundaryScanner">
|
class="solr.highlight.SimpleBoundaryScanner">
|
||||||
<lst name="defaults">
|
<lst name="defaults">
|
||||||
@ -1657,8 +1657,8 @@
|
|||||||
<str name="hl.bs.chars">.,!? 	 </str>
|
<str name="hl.bs.chars">.,!? 	 </str>
|
||||||
</lst>
|
</lst>
|
||||||
</boundaryScanner>
|
</boundaryScanner>
|
||||||
|
|
||||||
<boundaryScanner name="breakIterator"
|
<boundaryScanner name="breakIterator"
|
||||||
class="solr.highlight.BreakIteratorBoundaryScanner">
|
class="solr.highlight.BreakIteratorBoundaryScanner">
|
||||||
<lst name="defaults">
|
<lst name="defaults">
|
||||||
<!-- type should be one of CHARACTER, WORD(default), LINE and SENTENCE -->
|
<!-- type should be one of CHARACTER, WORD(default), LINE and SENTENCE -->
|
||||||
@ -1680,15 +1680,15 @@
|
|||||||
|
|
||||||
http://wiki.apache.org/solr/UpdateRequestProcessor
|
http://wiki.apache.org/solr/UpdateRequestProcessor
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<!-- Deduplication
|
<!-- Deduplication
|
||||||
|
|
||||||
An example dedup update processor that creates the "id" field
|
An example dedup update processor that creates the "id" field
|
||||||
on the fly based on the hash code of some other fields. This
|
on the fly based on the hash code of some other fields. This
|
||||||
example has overwriteDupes set to false since we are using the
|
example has overwriteDupes set to false since we are using the
|
||||||
id field as the signatureField and Solr will maintain
|
id field as the signatureField and Solr will maintain
|
||||||
uniqueness based on that anyway.
|
uniqueness based on that anyway.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<!--
|
<!--
|
||||||
<updateRequestProcessorChain name="dedupe">
|
<updateRequestProcessorChain name="dedupe">
|
||||||
@ -1703,7 +1703,7 @@
|
|||||||
<processor class="solr.RunUpdateProcessorFactory" />
|
<processor class="solr.RunUpdateProcessorFactory" />
|
||||||
</updateRequestProcessorChain>
|
</updateRequestProcessorChain>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- Language identification
|
<!-- Language identification
|
||||||
|
|
||||||
This example update chain identifies the language of the incoming
|
This example update chain identifies the language of the incoming
|
||||||
@ -1743,7 +1743,7 @@
|
|||||||
<processor class="solr.RunUpdateProcessorFactory" />
|
<processor class="solr.RunUpdateProcessorFactory" />
|
||||||
</updateRequestProcessorChain>
|
</updateRequestProcessorChain>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- Response Writers
|
<!-- Response Writers
|
||||||
|
|
||||||
http://wiki.apache.org/solr/QueryResponseWriter
|
http://wiki.apache.org/solr/QueryResponseWriter
|
||||||
@ -1759,7 +1759,7 @@
|
|||||||
overridden...
|
overridden...
|
||||||
-->
|
-->
|
||||||
<!--
|
<!--
|
||||||
<queryResponseWriter name="xml"
|
<queryResponseWriter name="xml"
|
||||||
default="true"
|
default="true"
|
||||||
class="solr.XMLResponseWriter" />
|
class="solr.XMLResponseWriter" />
|
||||||
<queryResponseWriter name="json" class="solr.JSONResponseWriter"/>
|
<queryResponseWriter name="json" class="solr.JSONResponseWriter"/>
|
||||||
@ -1778,16 +1778,16 @@
|
|||||||
-->
|
-->
|
||||||
<str name="content-type">text/plain; charset=UTF-8</str>
|
<str name="content-type">text/plain; charset=UTF-8</str>
|
||||||
</queryResponseWriter>
|
</queryResponseWriter>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Custom response writers can be declared as needed...
|
Custom response writers can be declared as needed...
|
||||||
-->
|
-->
|
||||||
<queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy"/>
|
<queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy"/>
|
||||||
|
|
||||||
|
|
||||||
<!-- XSLT response writer transforms the XML output by any xslt file found
|
<!-- XSLT response writer transforms the XML output by any xslt file found
|
||||||
in Solr's conf/xslt directory. Changes to xslt files are checked for
|
in Solr's conf/xslt directory. Changes to xslt files are checked for
|
||||||
every xsltCacheLifetimeSeconds.
|
every xsltCacheLifetimeSeconds.
|
||||||
-->
|
-->
|
||||||
<queryResponseWriter name="xslt" class="solr.XSLTResponseWriter">
|
<queryResponseWriter name="xslt" class="solr.XSLTResponseWriter">
|
||||||
<int name="xsltCacheLifetimeSeconds">5</int>
|
<int name="xsltCacheLifetimeSeconds">5</int>
|
||||||
@ -1815,11 +1815,11 @@
|
|||||||
-->
|
-->
|
||||||
<!-- example of registering a custom function parser -->
|
<!-- example of registering a custom function parser -->
|
||||||
<!--
|
<!--
|
||||||
<valueSourceParser name="myfunc"
|
<valueSourceParser name="myfunc"
|
||||||
class="com.mycompany.MyValueSourceParser" />
|
class="com.mycompany.MyValueSourceParser" />
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
||||||
<!-- Document Transformers
|
<!-- Document Transformers
|
||||||
http://wiki.apache.org/solr/DocTransformers
|
http://wiki.apache.org/solr/DocTransformers
|
||||||
-->
|
-->
|
||||||
@ -1828,12 +1828,12 @@
|
|||||||
<transformer name="db" class="com.mycompany.LoadFromDatabaseTransformer" >
|
<transformer name="db" class="com.mycompany.LoadFromDatabaseTransformer" >
|
||||||
<int name="connection">jdbc://....</int>
|
<int name="connection">jdbc://....</int>
|
||||||
</transformer>
|
</transformer>
|
||||||
|
|
||||||
To add a constant value to all docs, use:
|
To add a constant value to all docs, use:
|
||||||
<transformer name="mytrans2" class="org.apache.solr.response.transform.ValueAugmenterFactory" >
|
<transformer name="mytrans2" class="org.apache.solr.response.transform.ValueAugmenterFactory" >
|
||||||
<int name="value">5</int>
|
<int name="value">5</int>
|
||||||
</transformer>
|
</transformer>
|
||||||
|
|
||||||
If you want the user to still be able to change it with _value:something_ use this:
|
If you want the user to still be able to change it with _value:something_ use this:
|
||||||
<transformer name="mytrans3" class="org.apache.solr.response.transform.ValueAugmenterFactory" >
|
<transformer name="mytrans3" class="org.apache.solr.response.transform.ValueAugmenterFactory" >
|
||||||
<double name="defaultValue">5</double>
|
<double name="defaultValue">5</double>
|
||||||
@ -1843,7 +1843,7 @@
|
|||||||
EditorialMarkerFactory will do exactly that:
|
EditorialMarkerFactory will do exactly that:
|
||||||
<transformer name="qecBooster" class="org.apache.solr.response.transform.EditorialMarkerFactory" />
|
<transformer name="qecBooster" class="org.apache.solr.response.transform.EditorialMarkerFactory" />
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
||||||
<!-- Legacy config for the admin interface -->
|
<!-- Legacy config for the admin interface -->
|
||||||
<admin>
|
<admin>
|
||||||
|
@ -1,26 +1,13 @@
|
|||||||
# Troubleshooting
|
# Troubleshooting
|
||||||
|
|
||||||
## Newly indexed content only shows in searches after a delay
|
|
||||||
|
|
||||||
First, check how you're running index operations.
|
|
||||||
In many cases where the `queuedjobs` module is installed,
|
|
||||||
saving or publishing a record will create a new index job which needs to complete first.
|
|
||||||
Solr also distinguishes between adding documents to the indexing,
|
|
||||||
committing them, and making them available to new searches.
|
|
||||||
In most cases this happens within a few seconds, but
|
|
||||||
in sometimes it can take up to a minute due to the
|
|
||||||
`autoSoftCommit` configuration setting defaults in your `solrconfig.xml`.
|
|
||||||
To find out more detail, read about
|
|
||||||
[soft vs. hard commits](https://lucidworks.com/post/understanding-transaction-logs-softcommit-and-commit-in-sorlcloud/).
|
|
||||||
|
|
||||||
## Common gotchas
|
## Common gotchas
|
||||||
|
|
||||||
* By default number-letter boundaries are treated as a word boundary. For example, `A1` is two words - `a` and `1` - when Solr parses the search term.
|
* By default number-letter boundaries are treated as a word boundary. For example, `A1` is two words - `a` and `1` - when Solr parses the search term.
|
||||||
* Special characters and operators are not correctly escaped
|
* Special characters and operators are not correctly escaped
|
||||||
* Multi-word synonym issues
|
* Multi-word synonym issues
|
||||||
* When Solr indexes are reconfigured and reindexed, their content is trashed and rebuilt
|
* When Dolr indexes are reconfigured and reindexed, their content is trashed and rebuilt
|
||||||
|
|
||||||
## CWP-specific
|
### CWP-specific
|
||||||
|
|
||||||
* `solrconfig.xml` customisations fail silently
|
* `solrconfig.xml` customisations fail silently
|
||||||
* Developers aren’t able to test raw queries or see output via the
|
* Developers aren’t able to test raw queries or see output via the
|
||||||
|
10
lang/en.yml
10
lang/en.yml
@ -2,13 +2,3 @@ en:
|
|||||||
SilverStripe\FullTextSearch\Solr\Forms\SearchForm:
|
SilverStripe\FullTextSearch\Solr\Forms\SearchForm:
|
||||||
GO: Go
|
GO: Go
|
||||||
SEARCH: Search
|
SEARCH: Search
|
||||||
SolrResultsPage:
|
|
||||||
DidYouMean: 'Did you mean'
|
|
||||||
NoResults: 'Sorry, your search query did not return any results.'
|
|
||||||
Page: Page
|
|
||||||
ReadMore: 'Read more about'
|
|
||||||
SearchQuery: 'You searched for'
|
|
||||||
ViewNextPage: 'View the next page'
|
|
||||||
ViewPageNumber: 'View page number'
|
|
||||||
ViewPreviousPage: 'View the previous page'
|
|
||||||
of: of
|
|
||||||
|
14
lang/eo.yml
14
lang/eo.yml
@ -1,14 +0,0 @@
|
|||||||
eo:
|
|
||||||
SilverStripe\FullTextSearch\Solr\Forms\SearchForm:
|
|
||||||
GO: Iri
|
|
||||||
SEARCH: Serĉi
|
|
||||||
SolrResultsPage:
|
|
||||||
DidYouMean: 'Ĉu vi intencis'
|
|
||||||
NoResults: 'Bedaŭrinde via serĉpeto ne liveris rezultojn.'
|
|
||||||
Page: Paĝo
|
|
||||||
ReadMore: 'Legi pli pri'
|
|
||||||
SearchQuery: 'Vi serĉis por'
|
|
||||||
ViewNextPage: 'Vidi la sekvan paĝon'
|
|
||||||
ViewPageNumber: 'Vidi paĝnumeron'
|
|
||||||
ViewPreviousPage: 'Vidi la antaŭan paĝon'
|
|
||||||
of: de
|
|
14
lang/fi.yml
14
lang/fi.yml
@ -3,12 +3,12 @@ fi:
|
|||||||
GO: Hae
|
GO: Hae
|
||||||
SEARCH: Haku
|
SEARCH: Haku
|
||||||
SolrResultsPage:
|
SolrResultsPage:
|
||||||
DidYouMean: Tarkoititko
|
|
||||||
NoResults: 'Pahoittelut, mutta hakusi ei tuottanut yhtään osumaa.'
|
|
||||||
Page: Sivu
|
|
||||||
ReadMore: 'Lue lisää'
|
|
||||||
SearchQuery: 'Hakusanasi oli'
|
SearchQuery: 'Hakusanasi oli'
|
||||||
'View page number': 'Siirry sivulle'
|
DidYouMean: 'Tarkoititko'
|
||||||
ViewNextPage: 'Katso seuraava sivu'
|
ReadMore: 'Lue lisää'
|
||||||
|
NoResults: 'Pahoittelut, mutta hakusi ei tuottanut yhtään osumaa.'
|
||||||
|
Page: 'Sivu'
|
||||||
|
of: '/'
|
||||||
ViewPreviousPage: 'Katso edellinen sivu'
|
ViewPreviousPage: 'Katso edellinen sivu'
|
||||||
of: /
|
View page number: 'Siirry sivulle'
|
||||||
|
ViewNextPage: 'Katso seuraava sivu'
|
||||||
|
14
lang/nl.yml
14
lang/nl.yml
@ -1,14 +0,0 @@
|
|||||||
nl:
|
|
||||||
SilverStripe\FullTextSearch\Solr\Forms\SearchForm:
|
|
||||||
GO: Zoek
|
|
||||||
SEARCH: Zoeken
|
|
||||||
SolrResultsPage:
|
|
||||||
DidYouMean: 'Bedoelde je'
|
|
||||||
NoResults: 'Helaas, deze zoekterm heeft geen resultaten opgeleverd.'
|
|
||||||
Page: Pagina
|
|
||||||
ReadMore: 'Lees meer over'
|
|
||||||
SearchQuery: 'Er is gezocht op'
|
|
||||||
ViewNextPage: 'Bekijk volgende pagina'
|
|
||||||
ViewPageNumber: 'Bekijk pagina'
|
|
||||||
ViewPreviousPage: 'Bekijk volgende pagina'
|
|
||||||
of: van
|
|
14
lang/sl.yml
14
lang/sl.yml
@ -1,14 +0,0 @@
|
|||||||
sl:
|
|
||||||
SilverStripe\FullTextSearch\Solr\Forms\SearchForm:
|
|
||||||
GO: Išči
|
|
||||||
SEARCH: Iskanje
|
|
||||||
SolrResultsPage:
|
|
||||||
DidYouMean: 'Ste morda mislili'
|
|
||||||
NoResults: 'Fraze, ki ste jo iskali, nismo našli.'
|
|
||||||
Page: Stran
|
|
||||||
ReadMore: 'Več o'
|
|
||||||
SearchQuery: 'Iskali ste'
|
|
||||||
ViewNextPage: Naslednja
|
|
||||||
ViewPageNumber: 'Skoči na stran'
|
|
||||||
ViewPreviousPage: Prejšnja
|
|
||||||
of: od
|
|
14
lang/sv.yml
14
lang/sv.yml
@ -1,14 +0,0 @@
|
|||||||
sv:
|
|
||||||
SilverStripe\FullTextSearch\Solr\Forms\SearchForm:
|
|
||||||
GO: Gå
|
|
||||||
SEARCH: Sök
|
|
||||||
SolrResultsPage:
|
|
||||||
DidYouMean: 'Menade du'
|
|
||||||
NoResults: 'Förlåt, din sökfråga gav inga resultat.'
|
|
||||||
Page: Sida
|
|
||||||
ReadMore: 'Läs mera om'
|
|
||||||
SearchQuery: 'Du sökte efter'
|
|
||||||
ViewNextPage: 'Visa nästa sida'
|
|
||||||
ViewPageNumber: 'Visa sidnummer'
|
|
||||||
ViewPreviousPage: 'Visa föregående sida'
|
|
||||||
of: av
|
|
@ -1,4 +1,3 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<phpunit bootstrap="vendor/silverstripe/cms/tests/bootstrap.php" colors="true">
|
<phpunit bootstrap="vendor/silverstripe/cms/tests/bootstrap.php" colors="true">
|
||||||
<testsuites>
|
<testsuites>
|
||||||
<testsuite name="Default">
|
<testsuite name="Default">
|
||||||
|
@ -2,12 +2,11 @@
|
|||||||
|
|
||||||
namespace SilverStripe\FullTextSearch\Search\Captures;
|
namespace SilverStripe\FullTextSearch\Search\Captures;
|
||||||
|
|
||||||
use SilverStripe\Dev\Deprecation;
|
|
||||||
use SilverStripe\ORM\Connect\MySQLDatabase;
|
use SilverStripe\ORM\Connect\MySQLDatabase;
|
||||||
use SilverStripe\FullTextSearch\Search\Updaters\SearchUpdater;
|
use SilverStripe\FullTextSearch\Search\Updaters\SearchUpdater;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.1.0 Use tractorcow/silverstripe-proxy-db to proxy the database connector instead
|
* @deprecated 3.1...4.0 Please use tractorcow/silverstripe-proxy-db to proxy the database connector instead
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class SearchManipulateCapture_MySQLDatabase extends MySQLDatabase
|
class SearchManipulateCapture_MySQLDatabase extends MySQLDatabase
|
||||||
@ -15,11 +14,6 @@ class SearchManipulateCapture_MySQLDatabase extends MySQLDatabase
|
|||||||
|
|
||||||
public $isManipulationCapture = true;
|
public $isManipulationCapture = true;
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
Deprecation::notice('3.1.0', 'Use tractorcow/silverstripe-proxy-db to proxy the database connector instead', Deprecation::SCOPE_CLASS);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function manipulate($manipulation)
|
public function manipulate($manipulation)
|
||||||
{
|
{
|
||||||
$res = parent::manipulate($manipulation);
|
$res = parent::manipulate($manipulation);
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace SilverStripe\FullTextSearch\Search\Captures;
|
namespace SilverStripe\FullTextSearch\Search\Captures;
|
||||||
|
|
||||||
use SilverStripe\Dev\Deprecation;
|
|
||||||
use SilverStripe\PostgreSQL\PostgreSQLDatabase;
|
use SilverStripe\PostgreSQL\PostgreSQLDatabase;
|
||||||
use SilverStripe\FullTextSearch\Search\Updaters\SearchUpdater;
|
use SilverStripe\FullTextSearch\Search\Updaters\SearchUpdater;
|
||||||
|
|
||||||
@ -11,17 +10,13 @@ if (!class_exists(PostgreSQLDatabase::class)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.1.0 Use tractorcow/silverstripe-proxy-db to proxy the database connector instead
|
* @deprecated 3.1...4.0 Please use tractorcow/silverstripe-proxy-db to proxy the database connector instead
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class SearchManipulateCapture_PostgreSQLDatabase extends PostgreSQLDatabase
|
class SearchManipulateCapture_PostgreSQLDatabase extends PostgreSQLDatabase
|
||||||
{
|
{
|
||||||
public $isManipulationCapture = true;
|
public $isManipulationCapture = true;
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
Deprecation::notice('3.1.0', 'Use tractorcow/silverstripe-proxy-db to proxy the database connector instead', Deprecation::SCOPE_CLASS);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function manipulate($manipulation)
|
public function manipulate($manipulation)
|
||||||
{
|
{
|
||||||
$res = parent::manipulate($manipulation);
|
$res = parent::manipulate($manipulation);
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace SilverStripe\FullTextSearch\Search\Captures;
|
namespace SilverStripe\FullTextSearch\Search\Captures;
|
||||||
|
|
||||||
use SilverStripe\Dev\Deprecation;
|
|
||||||
use SilverStripe\FullTextSearch\Search\Updaters\SearchUpdater;
|
use SilverStripe\FullTextSearch\Search\Updaters\SearchUpdater;
|
||||||
use SilverStripe\SQLite\SQLite3Database;
|
use SilverStripe\SQLite\SQLite3Database;
|
||||||
|
|
||||||
@ -11,7 +10,7 @@ if (!class_exists(SQLite3Database::class)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.1.0 Use tractorcow/silverstripe-proxy-db to proxy the database connector instead
|
* @deprecated 3.1...4.0 Please use tractorcow/silverstripe-proxy-db to proxy the database connector instead
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class SearchManipulateCapture_SQLite3Database extends SQLite3Database
|
class SearchManipulateCapture_SQLite3Database extends SQLite3Database
|
||||||
@ -19,11 +18,6 @@ class SearchManipulateCapture_SQLite3Database extends SQLite3Database
|
|||||||
|
|
||||||
public $isManipulationCapture = true;
|
public $isManipulationCapture = true;
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
Deprecation::notice('3.1.0', 'Use tractorcow/silverstripe-proxy-db to proxy the database connector instead', Deprecation::SCOPE_CLASS);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function manipulate($manipulation)
|
public function manipulate($manipulation)
|
||||||
{
|
{
|
||||||
$res = parent::manipulate($manipulation);
|
$res = parent::manipulate($manipulation);
|
||||||
|
@ -222,7 +222,7 @@ class SearchCriteria implements SearchCriteriaInterface
|
|||||||
protected function getConjunction($key)
|
protected function getConjunction($key)
|
||||||
{
|
{
|
||||||
$conjunctions = $this->getConjunctions();
|
$conjunctions = $this->getConjunctions();
|
||||||
if (!array_key_exists($key, $conjunctions ?? [])) {
|
if (!array_key_exists($key, $conjunctions)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ class FullTextSearch
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($hidden) {
|
if ($hidden) {
|
||||||
$candidates = array_diff($candidates ?? [], $hidden);
|
$candidates = array_diff($candidates, $hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create all indexes
|
// Create all indexes
|
||||||
@ -86,7 +86,7 @@ class FullTextSearch
|
|||||||
|
|
||||||
$valid = array();
|
$valid = array();
|
||||||
foreach ($all as $indexclass => $instance) {
|
foreach ($all as $indexclass => $instance) {
|
||||||
if (is_subclass_of($indexclass, $class ?? '')) {
|
if (is_subclass_of($indexclass, $class)) {
|
||||||
$valid[$indexclass] = $instance;
|
$valid[$indexclass] = $instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ abstract class SearchIndex extends ViewableData
|
|||||||
*/
|
*/
|
||||||
protected function getSourceName($source)
|
protected function getSourceName($source)
|
||||||
{
|
{
|
||||||
$source = explode(self::config()->get('class_delimiter') ?? '', $source ?? '');
|
$source = explode(self::config()->get('class_delimiter'), $source);
|
||||||
|
|
||||||
return $source[0];
|
return $source[0];
|
||||||
}
|
}
|
||||||
@ -102,7 +102,7 @@ abstract class SearchIndex extends ViewableData
|
|||||||
*/
|
*/
|
||||||
public function fieldData($field, $forceType = null, $extraOptions = [])
|
public function fieldData($field, $forceType = null, $extraOptions = [])
|
||||||
{
|
{
|
||||||
$fullfield = str_replace(".", "_", $field ?? '');
|
$fullfield = str_replace(".", "_", $field);
|
||||||
$sources = $this->getClasses();
|
$sources = $this->getClasses();
|
||||||
|
|
||||||
foreach ($sources as $source => $options) {
|
foreach ($sources as $source => $options) {
|
||||||
@ -112,8 +112,8 @@ abstract class SearchIndex extends ViewableData
|
|||||||
|
|
||||||
$found = [];
|
$found = [];
|
||||||
|
|
||||||
if (strpos($field ?? '', '.') !== false) {
|
if (strpos($field, '.') !== false) {
|
||||||
$lookups = explode(".", $field ?? '');
|
$lookups = explode(".", $field);
|
||||||
$field = array_pop($lookups);
|
$field = array_pop($lookups);
|
||||||
|
|
||||||
foreach ($lookups as $lookup) {
|
foreach ($lookups as $lookup) {
|
||||||
@ -133,7 +133,7 @@ abstract class SearchIndex extends ViewableData
|
|||||||
// we only want to include base class for relation, omit classes that inherited the relation
|
// 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 = Config::inst()->get($dataclass, 'has_one', Config::UNINHERITED);
|
||||||
$relationList = (!is_null($relationList)) ? $relationList : [];
|
$relationList = (!is_null($relationList)) ? $relationList : [];
|
||||||
if (!array_key_exists($lookup, $relationList ?? [])) {
|
if (!array_key_exists($lookup, $relationList)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ abstract class SearchIndex extends ViewableData
|
|||||||
// we only want to include base class for relation, omit classes that inherited the relation
|
// 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 = Config::inst()->get($dataclass, 'has_many', Config::UNINHERITED);
|
||||||
$relationList = (!is_null($relationList)) ? $relationList : [];
|
$relationList = (!is_null($relationList)) ? $relationList : [];
|
||||||
if (!array_key_exists($lookup, $relationList ?? [])) {
|
if (!array_key_exists($lookup, $relationList)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ abstract class SearchIndex extends ViewableData
|
|||||||
// we only want to include base class for relation, omit classes that inherited the relation
|
// 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 = Config::inst()->get($dataclass, 'many_many', Config::UNINHERITED);
|
||||||
$relationList = (!is_null($relationList)) ? $relationList : [];
|
$relationList = (!is_null($relationList)) ? $relationList : [];
|
||||||
if (!array_key_exists($lookup, $relationList ?? [])) {
|
if (!array_key_exists($lookup, $relationList)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ abstract class SearchIndex extends ViewableData
|
|||||||
$class = $this->getSourceName($class);
|
$class = $this->getSourceName($class);
|
||||||
$dataclasses = SearchIntrospection::hierarchy($class, $options['include_children']);
|
$dataclasses = SearchIntrospection::hierarchy($class, $options['include_children']);
|
||||||
|
|
||||||
while (count($dataclasses ?? [])) {
|
while (count($dataclasses)) {
|
||||||
$dataclass = array_shift($dataclasses);
|
$dataclass = array_shift($dataclasses);
|
||||||
$type = null;
|
$type = null;
|
||||||
$fieldoptions = $options;
|
$fieldoptions = $options;
|
||||||
@ -228,9 +228,9 @@ abstract class SearchIndex extends ViewableData
|
|||||||
|
|
||||||
if ($type) {
|
if ($type) {
|
||||||
// Don't search through child classes of a class we matched on. TODO: Should we?
|
// Don't search through child classes of a class we matched on. TODO: Should we?
|
||||||
$dataclasses = array_diff($dataclasses ?? [], array_values(ClassInfo::subclassesFor($dataclass) ?? []));
|
$dataclasses = array_diff($dataclasses, array_values(ClassInfo::subclassesFor($dataclass)));
|
||||||
// Trim arguments off the type string
|
// Trim arguments off the type string
|
||||||
if (preg_match('/^(\w+)\(/', $type ?? '', $match)) {
|
if (preg_match('/^(\w+)\(/', $type, $match)) {
|
||||||
$type = $match[1];
|
$type = $match[1];
|
||||||
}
|
}
|
||||||
// Get the origin
|
// Get the origin
|
||||||
@ -412,7 +412,7 @@ abstract class SearchIndex extends ViewableData
|
|||||||
|
|
||||||
public function buildDependancyList()
|
public function buildDependancyList()
|
||||||
{
|
{
|
||||||
$this->dependancyList = array_keys($this->getClasses() ?? []);
|
$this->dependancyList = array_keys($this->getClasses());
|
||||||
|
|
||||||
foreach ($this->getFieldsIterator() as $name => $field) {
|
foreach ($this->getFieldsIterator() as $name => $field) {
|
||||||
if (!isset($field['class'])) {
|
if (!isset($field['class'])) {
|
||||||
@ -434,7 +434,7 @@ abstract class SearchIndex extends ViewableData
|
|||||||
$this->derivedFields = array();
|
$this->derivedFields = array();
|
||||||
|
|
||||||
foreach ($this->getFieldsIterator() as $name => $field) {
|
foreach ($this->getFieldsIterator() as $name => $field) {
|
||||||
if (count($field['lookup_chain'] ?? []) < 2) {
|
if (count($field['lookup_chain']) < 2) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,7 +445,7 @@ abstract class SearchIndex extends ViewableData
|
|||||||
$this->derivedFields[$key]['fields'][$fieldname] = $fieldname;
|
$this->derivedFields[$key]['fields'][$fieldname] = $fieldname;
|
||||||
SearchIntrospection::add_unique_by_ancestor($this->derivedFields['classes'], $field['class']);
|
SearchIntrospection::add_unique_by_ancestor($this->derivedFields['classes'], $field['class']);
|
||||||
} else {
|
} else {
|
||||||
$chain = array_reverse($field['lookup_chain'] ?? []);
|
$chain = array_reverse($field['lookup_chain']);
|
||||||
array_shift($chain);
|
array_shift($chain);
|
||||||
|
|
||||||
$this->derivedFields[$key] = array(
|
$this->derivedFields[$key] = array(
|
||||||
@ -473,7 +473,7 @@ abstract class SearchIndex extends ViewableData
|
|||||||
{
|
{
|
||||||
ksort($state);
|
ksort($state);
|
||||||
$parts = array('id' => $id, 'base' => $base, 'state' => json_encode($state));
|
$parts = array('id' => $id, 'base' => $base, 'state' => json_encode($state));
|
||||||
return implode('-', array_values($parts ?? []));
|
return implode('-', array_values($parts));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -501,7 +501,7 @@ abstract class SearchIndex extends ViewableData
|
|||||||
$errorHandler = function ($no, $str) {
|
$errorHandler = function ($no, $str) {
|
||||||
throw new Exception('HTML Parse Error: ' . $str);
|
throw new Exception('HTML Parse Error: ' . $str);
|
||||||
};
|
};
|
||||||
set_error_handler($errorHandler, E_ALL & ~(E_DEPRECATED | E_USER_DEPRECATED));
|
set_error_handler($errorHandler, E_ALL);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
foreach ($field['lookup_chain'] as $step) {
|
foreach ($field['lookup_chain'] as $step) {
|
||||||
@ -586,7 +586,7 @@ abstract class SearchIndex extends ViewableData
|
|||||||
|
|
||||||
// First, if this object is directly contained in the index, add it
|
// First, if this object is directly contained in the index, add it
|
||||||
foreach ($this->classes as $searchclass => $options) {
|
foreach ($this->classes as $searchclass => $options) {
|
||||||
if ($searchclass == $class || ($options['include_children'] && is_subclass_of($class, $searchclass ?? ''))) {
|
if ($searchclass == $class || ($options['include_children'] && is_subclass_of($class, $searchclass))) {
|
||||||
$base = DataObject::getSchema()->baseDataClass($searchclass);
|
$base = DataObject::getSchema()->baseDataClass($searchclass);
|
||||||
$dirty[$base] = array();
|
$dirty[$base] = array();
|
||||||
foreach ($statefulids as $statefulid) {
|
foreach ($statefulids as $statefulid) {
|
||||||
@ -605,7 +605,7 @@ abstract class SearchIndex extends ViewableData
|
|||||||
if (!SearchIntrospection::is_subclass_of($class, $derivation['classes'])) {
|
if (!SearchIntrospection::is_subclass_of($class, $derivation['classes'])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!array_intersect_key($fields ?? [], $derivation['fields'])) {
|
if (!array_intersect_key($fields, $derivation['fields'])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ abstract class SearchUpdateBatchedProcessor extends SearchUpdateProcessor
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Don't re-process completed queue
|
// Don't re-process completed queue
|
||||||
if ($this->currentBatch >= count($this->batches ?? [])) {
|
if ($this->currentBatch >= count($this->batches)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,14 +138,14 @@ abstract class SearchUpdateBatchedProcessor extends SearchUpdateProcessor
|
|||||||
while ($ids) {
|
while ($ids) {
|
||||||
// Estimate maximum number of items to take for this iteration, allowing for the soft cap
|
// Estimate maximum number of items to take for this iteration, allowing for the soft cap
|
||||||
$take = $batchSize - $currentSize;
|
$take = $batchSize - $currentSize;
|
||||||
if (count($ids ?? []) <= $take + $softCap) {
|
if (count($ids) <= $take + $softCap) {
|
||||||
$take += $softCap;
|
$take += $softCap;
|
||||||
}
|
}
|
||||||
$items = array_slice($ids ?? [], 0, $take, true);
|
$items = array_slice($ids, 0, $take, true);
|
||||||
$ids = array_slice($ids ?? [], count($items ?? []), null, true);
|
$ids = array_slice($ids, count($items), null, true);
|
||||||
|
|
||||||
// Update batch
|
// Update batch
|
||||||
$currentSize += count($items ?? []);
|
$currentSize += count($items);
|
||||||
$merge = array(
|
$merge = array(
|
||||||
$base => array(
|
$base => array(
|
||||||
$stateKey => array(
|
$stateKey => array(
|
||||||
|
@ -97,7 +97,7 @@ class SearchUpdateCommitJobProcessor implements QueuedJob
|
|||||||
|
|
||||||
if ($dirty) {
|
if ($dirty) {
|
||||||
$indexes = FullTextSearch::get_indexes();
|
$indexes = FullTextSearch::get_indexes();
|
||||||
static::$dirty_indexes = array_keys($indexes ?? []);
|
static::$dirty_indexes = array_keys($indexes);
|
||||||
}
|
}
|
||||||
return $id;
|
return $id;
|
||||||
}
|
}
|
||||||
@ -126,7 +126,7 @@ class SearchUpdateCommitJobProcessor implements QueuedJob
|
|||||||
{
|
{
|
||||||
if (empty($this->indexes)) {
|
if (empty($this->indexes)) {
|
||||||
$indexes = FullTextSearch::get_indexes();
|
$indexes = FullTextSearch::get_indexes();
|
||||||
$this->indexes = array_keys($indexes ?? []);
|
$this->indexes = array_keys($indexes);
|
||||||
}
|
}
|
||||||
return $this->indexes;
|
return $this->indexes;
|
||||||
}
|
}
|
||||||
@ -135,7 +135,7 @@ class SearchUpdateCommitJobProcessor implements QueuedJob
|
|||||||
{
|
{
|
||||||
// If we've indexed exactly as many as we would like, we are done
|
// If we've indexed exactly as many as we would like, we are done
|
||||||
return $this->skipped
|
return $this->skipped
|
||||||
|| (count($this->getAllIndexes() ?? []) <= count($this->completed ?? []));
|
|| (count($this->getAllIndexes()) <= count($this->completed));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function prepareForRestart()
|
public function prepareForRestart()
|
||||||
@ -213,7 +213,7 @@ class SearchUpdateCommitJobProcessor implements QueuedJob
|
|||||||
{
|
{
|
||||||
// Skip index if this is already complete
|
// Skip index if this is already complete
|
||||||
$name = get_class($index);
|
$name = get_class($index);
|
||||||
if (in_array($name, $this->completed ?? [])) {
|
if (in_array($name, $this->completed)) {
|
||||||
$this->addMessage("Skipping already comitted index {$name}");
|
$this->addMessage("Skipping already comitted index {$name}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -240,8 +240,8 @@ class SearchUpdateCommitJobProcessor implements QueuedJob
|
|||||||
public function getJobData()
|
public function getJobData()
|
||||||
{
|
{
|
||||||
$data = new stdClass();
|
$data = new stdClass();
|
||||||
$data->totalSteps = count($this->getAllIndexes() ?? []);
|
$data->totalSteps = count($this->getAllIndexes());
|
||||||
$data->currentStep = count($this->completed ?? []);
|
$data->currentStep = count($this->completed);
|
||||||
$data->isComplete = $this->jobFinished();
|
$data->isComplete = $this->jobFinished();
|
||||||
$data->messages = $this->messages;
|
$data->messages = $this->messages;
|
||||||
|
|
||||||
@ -265,7 +265,7 @@ class SearchUpdateCommitJobProcessor implements QueuedJob
|
|||||||
|
|
||||||
public function addMessage($message, $severity = 'INFO')
|
public function addMessage($message, $severity = 'INFO')
|
||||||
{
|
{
|
||||||
$severity = strtoupper($severity ?? '');
|
$severity = strtoupper($severity);
|
||||||
$this->messages[] = '[' . date('Y-m-d H:i:s') . "][$severity] $message";
|
$this->messages[] = '[' . date('Y-m-d H:i:s') . "][$severity] $message";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ namespace SilverStripe\FullTextSearch\Search\Processors;
|
|||||||
use SilverStripe\FullTextSearch\Search\Services\SearchableService;
|
use SilverStripe\FullTextSearch\Search\Services\SearchableService;
|
||||||
use SilverStripe\FullTextSearch\Search\Variants\SearchVariantVersioned;
|
use SilverStripe\FullTextSearch\Search\Variants\SearchVariantVersioned;
|
||||||
use SilverStripe\ORM\DataObject;
|
use SilverStripe\ORM\DataObject;
|
||||||
use SilverStripe\ORM\DB;
|
|
||||||
use SilverStripe\FullTextSearch\Search\Variants\SearchVariant;
|
use SilverStripe\FullTextSearch\Search\Variants\SearchVariant;
|
||||||
use SilverStripe\FullTextSearch\Search\FullTextSearch;
|
use SilverStripe\FullTextSearch\Search\FullTextSearch;
|
||||||
use SilverStripe\Versioned\Versioned;
|
use SilverStripe\Versioned\Versioned;
|
||||||
@ -55,7 +54,7 @@ abstract class SearchUpdateProcessor
|
|||||||
$forclass[$statekey] = array('state' => $state, 'ids' => array($id => array($index)));
|
$forclass[$statekey] = array('state' => $state, 'ids' => array($id => array($index)));
|
||||||
} elseif (!isset($forclass[$statekey]['ids'][$id])) {
|
} elseif (!isset($forclass[$statekey]['ids'][$id])) {
|
||||||
$forclass[$statekey]['ids'][$id] = array($index);
|
$forclass[$statekey]['ids'][$id] = array($index);
|
||||||
} elseif (array_search($index, $forclass[$statekey]['ids'][$id] ?? []) === false) {
|
} elseif (array_search($index, $forclass[$statekey]['ids'][$id]) === false) {
|
||||||
$forclass[$statekey]['ids'][$id][] = $index;
|
$forclass[$statekey]['ids'][$id][] = $index;
|
||||||
// dirty count stays the same
|
// dirty count stays the same
|
||||||
}
|
}
|
||||||
@ -89,7 +88,7 @@ abstract class SearchUpdateProcessor
|
|||||||
SearchVariant::activate_state($state);
|
SearchVariant::activate_state($state);
|
||||||
|
|
||||||
// Ensure that indexes for all new / updated objects are included
|
// Ensure that indexes for all new / updated objects are included
|
||||||
$objs = DataObject::get($base)->byIDs(array_keys($ids ?? []));
|
$objs = DataObject::get($base)->byIDs(array_keys($ids));
|
||||||
|
|
||||||
/** @var DataObject $obj */
|
/** @var DataObject $obj */
|
||||||
foreach ($objs as $obj) {
|
foreach ($objs as $obj) {
|
||||||
@ -155,9 +154,6 @@ abstract class SearchUpdateProcessor
|
|||||||
*/
|
*/
|
||||||
public function process()
|
public function process()
|
||||||
{
|
{
|
||||||
if (!DB::is_active()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Generate and commit all instances
|
// Generate and commit all instances
|
||||||
$indexes = $this->prepareIndexes();
|
$indexes = $this->prepareIndexes();
|
||||||
foreach ($indexes as $index) {
|
foreach ($indexes as $index) {
|
||||||
|
@ -45,7 +45,7 @@ class SearchUpdateQueuedJobProcessor extends SearchUpdateBatchedProcessor implem
|
|||||||
|
|
||||||
public function jobFinished()
|
public function jobFinished()
|
||||||
{
|
{
|
||||||
return $this->currentBatch >= count($this->batches ?? []);
|
return $this->currentBatch >= count($this->batches);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setup()
|
public function setup()
|
||||||
@ -68,7 +68,7 @@ class SearchUpdateQueuedJobProcessor extends SearchUpdateBatchedProcessor implem
|
|||||||
public function getJobData()
|
public function getJobData()
|
||||||
{
|
{
|
||||||
$data = new stdClass();
|
$data = new stdClass();
|
||||||
$data->totalSteps = count($this->batches ?? []);
|
$data->totalSteps = count($this->batches);
|
||||||
$data->currentStep = $this->currentBatch;
|
$data->currentStep = $this->currentBatch;
|
||||||
$data->isComplete = $this->jobFinished();
|
$data->isComplete = $this->jobFinished();
|
||||||
$data->messages = $this->messages;
|
$data->messages = $this->messages;
|
||||||
@ -91,7 +91,7 @@ class SearchUpdateQueuedJobProcessor extends SearchUpdateBatchedProcessor implem
|
|||||||
|
|
||||||
public function addMessage($message, $severity = 'INFO')
|
public function addMessage($message, $severity = 'INFO')
|
||||||
{
|
{
|
||||||
$severity = strtoupper($severity ?? '');
|
$severity = strtoupper($severity);
|
||||||
$this->messages[] = '[' . date('Y-m-d H:i:s') . "][$severity] $message";
|
$this->messages[] = '[' . date('Y-m-d H:i:s') . "][$severity] $message";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,81 +284,81 @@ class SearchQuery extends ViewableData
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
* @deprecated 4.0.0 Use addSearchTerm() instead
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
public function search($text, $fields = null, $boost = [])
|
public function search($text, $fields = null, $boost = [])
|
||||||
{
|
{
|
||||||
Deprecation::notice('4.0.0', 'Use addSearchTerm() instead');
|
Deprecation::notice('4.0', 'Use addSearchTerm() instead');
|
||||||
return $this->addSearchTerm($text, $fields, $boost);
|
return $this->addSearchTerm($text, $fields, $boost);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
* @deprecated 4.0.0 Use addFuzzySearchTerm() instead
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
public function fuzzysearch($text, $fields = null, $boost = [])
|
public function fuzzysearch($text, $fields = null, $boost = [])
|
||||||
{
|
{
|
||||||
Deprecation::notice('4.0.0', 'Use addFuzzySearchTerm() instead');
|
Deprecation::notice('4.0', 'Use addFuzzySearchTerm() instead');
|
||||||
return $this->addFuzzySearchTerm($text, $fields, $boost);
|
return $this->addFuzzySearchTerm($text, $fields, $boost);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
* @deprecated 4.0.0 Use addClassFilter() instead
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
public function inClass($class, $includeSubclasses = true)
|
public function inClass($class, $includeSubclasses = true)
|
||||||
{
|
{
|
||||||
Deprecation::notice('4.0.0', 'Use addClassFilter() instead');
|
Deprecation::notice('4.0', 'Use addClassFilter() instead');
|
||||||
return $this->addClassFilter($class, $includeSubclasses);
|
return $this->addClassFilter($class, $includeSubclasses);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
* @deprecated 4.0.0 Use addFilter() instead
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
public function filter($field, $values)
|
public function filter($field, $values)
|
||||||
{
|
{
|
||||||
Deprecation::notice('4.0.0', 'Use addFilter() instead');
|
Deprecation::notice('4.0', 'Use addFilter() instead');
|
||||||
return $this->addFilter($field, $values);
|
return $this->addFilter($field, $values);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
* @deprecated 4.0.0 Use addExclude() instead
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
public function exclude($field, $values)
|
public function exclude($field, $values)
|
||||||
{
|
{
|
||||||
Deprecation::notice('4.0.0', 'Use addExclude() instead');
|
Deprecation::notice('4.0', 'Use addExclude() instead');
|
||||||
return $this->addExclude($field, $values);
|
return $this->addExclude($field, $values);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
* @deprecated 4.0.0 Use setStart() instead
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
public function start($start)
|
public function start($start)
|
||||||
{
|
{
|
||||||
Deprecation::notice('4.0.0', 'Use setStart() instead');
|
Deprecation::notice('4.0', 'Use setStart() instead');
|
||||||
return $this->setStart($start);
|
return $this->setStart($start);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
* @deprecated 4.0.0 Use setLimit() instead
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
public function limit($limit)
|
public function limit($limit)
|
||||||
{
|
{
|
||||||
Deprecation::notice('4.0.0', 'Use setLimit() instead');
|
Deprecation::notice('4.0', 'Use setLimit() instead');
|
||||||
return $this->setLimit($limit);
|
return $this->setLimit($limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
* @deprecated 4.0.0 Use setPageSize() instead
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
public function page($page)
|
public function page($page)
|
||||||
{
|
{
|
||||||
Deprecation::notice('4.0.0', 'Use setPageSize() instead');
|
Deprecation::notice('4.0', 'Use setPageSize() instead');
|
||||||
return $this->setPageSize($page);
|
return $this->setPageSize($page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,22 +40,22 @@ class SearchQuery_Range
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 4.0.0 Use setStart() instead
|
* @deprecated
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
public function start($start)
|
public function start($start)
|
||||||
{
|
{
|
||||||
Deprecation::notice('4.0.0', 'Use setStart() instead');
|
Deprecation::notice('4.0', 'Use setStart() instead');
|
||||||
return $this->setStart($start);
|
return $this->setStart($start);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 4.0.0 Use setEnd() instead
|
* @deprecated
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
public function end($end)
|
public function end($end)
|
||||||
{
|
{
|
||||||
Deprecation::notice('4.0.0', 'Use setEnd() instead');
|
Deprecation::notice('4.0', 'Use setEnd() instead');
|
||||||
return $this->setEnd($end);
|
return $this->setEnd($end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ class SearchIntrospection
|
|||||||
public static function is_subclass_of($class, $of)
|
public static function is_subclass_of($class, $of)
|
||||||
{
|
{
|
||||||
$ancestry = isset(self::$ancestry[$class]) ? self::$ancestry[$class] : (self::$ancestry[$class] = ClassInfo::ancestry($class));
|
$ancestry = isset(self::$ancestry[$class]) ? self::$ancestry[$class] : (self::$ancestry[$class] = ClassInfo::ancestry($class));
|
||||||
return is_array($of) ? (bool)array_intersect($of, $ancestry) : array_key_exists($of, $ancestry ?? []);
|
return is_array($of) ? (bool)array_intersect($of, $ancestry) : array_key_exists($of, $ancestry);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static $hierarchy = array();
|
protected static $hierarchy = array();
|
||||||
@ -40,12 +40,12 @@ class SearchIntrospection
|
|||||||
$key = "$class!" . ($includeSubclasses ? 'sc' : 'an') . '!' . ($dataOnly ? 'do' : 'al');
|
$key = "$class!" . ($includeSubclasses ? 'sc' : 'an') . '!' . ($dataOnly ? 'do' : 'al');
|
||||||
|
|
||||||
if (!isset(self::$hierarchy[$key])) {
|
if (!isset(self::$hierarchy[$key])) {
|
||||||
$classes = array_values(ClassInfo::ancestry($class) ?? []);
|
$classes = array_values(ClassInfo::ancestry($class));
|
||||||
if ($includeSubclasses) {
|
if ($includeSubclasses) {
|
||||||
$classes = array_unique(array_merge($classes, array_values(ClassInfo::subclassesFor($class) ?? [])));
|
$classes = array_unique(array_merge($classes, array_values(ClassInfo::subclassesFor($class))));
|
||||||
}
|
}
|
||||||
|
|
||||||
$idx = array_search(DataObject::class, $classes ?? []);
|
$idx = array_search(DataObject::class, $classes);
|
||||||
if ($idx !== false) {
|
if ($idx !== false) {
|
||||||
array_splice($classes, 0, $idx+1);
|
array_splice($classes, 0, $idx+1);
|
||||||
}
|
}
|
||||||
@ -76,7 +76,7 @@ class SearchIntrospection
|
|||||||
|
|
||||||
// Strip out any subclasses of $class already in the list
|
// Strip out any subclasses of $class already in the list
|
||||||
$children = ClassInfo::subclassesFor($class);
|
$children = ClassInfo::subclassesFor($class);
|
||||||
$list = array_diff($list ?? [], $children);
|
$list = array_diff($list, $children);
|
||||||
|
|
||||||
// Then add the class in
|
// Then add the class in
|
||||||
$list[] = $class;
|
$list[] = $class;
|
||||||
|
@ -151,12 +151,12 @@ class SearchableService
|
|||||||
// Anonymous member canView() for indexing
|
// Anonymous member canView() for indexing
|
||||||
if (!$this->classSkipsCanViewCheck($objClass)) {
|
if (!$this->classSkipsCanViewCheck($objClass)) {
|
||||||
$value = Member::actAs(null, function () use ($obj) {
|
$value = Member::actAs(null, function () use ($obj) {
|
||||||
return (bool) $obj->canView();
|
return $obj->canView();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Current member canView() check for retrieving search results
|
// Current member canView() check for retrieving search results
|
||||||
$value = (bool) $obj->canView();
|
$value = $obj->canView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->extend('updateIsSearchable', $obj, $indexing, $value);
|
$this->extend('updateIsSearchable', $obj, $indexing, $value);
|
||||||
@ -199,11 +199,11 @@ class SearchableService
|
|||||||
if (empty($skipClasses)) {
|
if (empty($skipClasses)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (in_array($class, $skipClasses ?? [])) {
|
if (in_array($class, $skipClasses)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
foreach ($skipClasses as $skipClass) {
|
foreach ($skipClasses as $skipClass) {
|
||||||
if (in_array($skipClass, class_parents($class) ?? [])) {
|
if (in_array($skipClass, class_parents($class))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ class SearchUpdater
|
|||||||
'command' => $command,
|
'command' => $command,
|
||||||
'fields' => array()
|
'fields' => array()
|
||||||
);
|
);
|
||||||
} elseif (is_subclass_of($class, $writes[$key]['class'] ?? '')) {
|
} elseif (is_subclass_of($class, $writes[$key]['class'])) {
|
||||||
// Otherwise update the class label if it's more specific than the currently recorded one
|
// Otherwise update the class label if it's more specific than the currently recorded one
|
||||||
$writes[$key]['class'] = $class;
|
$writes[$key]['class'] = $class;
|
||||||
}
|
}
|
||||||
@ -118,7 +118,7 @@ class SearchUpdater
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Trim non-delete records without fields
|
// Trim non-delete records without fields
|
||||||
foreach (array_keys($writes ?? []) as $key) {
|
foreach (array_keys($writes) as $key) {
|
||||||
if ($writes[$key]['command'] !== 'delete' && empty($writes[$key]['fields'])) {
|
if ($writes[$key]['command'] !== 'delete' && empty($writes[$key]['fields'])) {
|
||||||
unset($writes[$key]);
|
unset($writes[$key]);
|
||||||
}
|
}
|
||||||
|
@ -105,9 +105,6 @@ abstract class SearchVariant
|
|||||||
$ref = new ReflectionClass($variantclass);
|
$ref = new ReflectionClass($variantclass);
|
||||||
if ($ref->isInstantiable()) {
|
if ($ref->isInstantiable()) {
|
||||||
$variant = singleton($variantclass);
|
$variant = singleton($variantclass);
|
||||||
// reassign actual class since Injector could be involved when creating the singleton
|
|
||||||
$variantclass = get_class($variant);
|
|
||||||
|
|
||||||
if ($variant->appliesToEnvironment()) {
|
if ($variant->appliesToEnvironment()) {
|
||||||
$concrete[$variantclass] = $variant;
|
$concrete[$variantclass] = $variant;
|
||||||
}
|
}
|
||||||
@ -205,7 +202,7 @@ abstract class SearchVariant
|
|||||||
// Merge the variants applicable to the current class into the list of common variants, using
|
// Merge the variants applicable to the current class into the list of common variants, using
|
||||||
// the variant instance to replace any previous versions for the same class name (should be singleton
|
// the variant instance to replace any previous versions for the same class name (should be singleton
|
||||||
// anyway).
|
// anyway).
|
||||||
$commonVariants = array_replace($commonVariants ?? [], $variantsForClass);
|
$commonVariants = array_replace($commonVariants, $variantsForClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache for future calls
|
// Cache for future calls
|
||||||
@ -325,7 +322,7 @@ abstract class SearchVariant
|
|||||||
$merged = array_values(array_unique(array_merge($left, $right)));
|
$merged = array_values(array_unique(array_merge($left, $right)));
|
||||||
|
|
||||||
// If there is only one item, return it as a single string
|
// If there is only one item, return it as a single string
|
||||||
if (count($merged ?? []) === 1) {
|
if (count($merged) === 1) {
|
||||||
return reset($merged);
|
return reset($merged);
|
||||||
}
|
}
|
||||||
return $merged;
|
return $merged;
|
||||||
|
@ -65,7 +65,7 @@ class SearchVariantVersioned extends SearchVariant
|
|||||||
$class = $details['class'];
|
$class = $details['class'];
|
||||||
$stage = Versioned::DRAFT;
|
$stage = Versioned::DRAFT;
|
||||||
|
|
||||||
if (preg_match('/^(.*)_' . Versioned::LIVE . '$/', $table ?? '', $matches)) {
|
if (preg_match('/^(.*)_' . Versioned::LIVE . '$/', $table, $matches)) {
|
||||||
$class = DataObject::getSchema()->tableClass($matches[1]);
|
$class = DataObject::getSchema()->tableClass($matches[1]);
|
||||||
$stage = Versioned::LIVE;
|
$stage = Versioned::LIVE;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ class SearchVariant_Caller
|
|||||||
$values = array();
|
$values = array();
|
||||||
|
|
||||||
foreach ($this->variants as $variant) {
|
foreach ($this->variants as $variant) {
|
||||||
if (method_exists($variant, $method ?? '')) {
|
if (method_exists($variant, $method)) {
|
||||||
$value = $variant->$method(...$args);
|
$value = $variant->$method(...$args);
|
||||||
if ($value !== null) {
|
if ($value !== null) {
|
||||||
$values[] = $value;
|
$values[] = $value;
|
||||||
|
@ -81,9 +81,9 @@ abstract class SolrReindexBase implements SolrReindexHandler
|
|||||||
|
|
||||||
// Apply filter
|
// Apply filter
|
||||||
if (!is_array($filterClasses)) {
|
if (!is_array($filterClasses)) {
|
||||||
$filterClasses = explode(',', $filterClasses ?? '');
|
$filterClasses = explode(',', $filterClasses);
|
||||||
}
|
}
|
||||||
return array_intersect_key($classes ?? [], array_combine($filterClasses ?? [], $filterClasses ?? []));
|
return array_intersect_key($classes, array_combine($filterClasses, $filterClasses));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -77,26 +77,27 @@ class SolrReindexImmediateHandler extends SolrReindexBase
|
|||||||
$indexClass = get_class($indexInstance);
|
$indexClass = get_class($indexInstance);
|
||||||
|
|
||||||
// Build script parameters
|
// Build script parameters
|
||||||
|
$indexClassEscaped = $indexClass;
|
||||||
$statevar = json_encode($state);
|
$statevar = json_encode($state);
|
||||||
|
|
||||||
|
if (strpos(PHP_OS, "WIN") !== false) {
|
||||||
|
$statevar = '"' . str_replace('"', '\\"', $statevar) . '"';
|
||||||
|
} else {
|
||||||
|
$statevar = "'" . $statevar . "'";
|
||||||
|
$class = addslashes($class);
|
||||||
|
$indexClassEscaped = addslashes($indexClass);
|
||||||
|
}
|
||||||
|
|
||||||
$php = Environment::getEnv('SS_PHP_BIN') ?: Config::inst()->get(static::class, 'php_bin');
|
$php = Environment::getEnv('SS_PHP_BIN') ?: Config::inst()->get(static::class, 'php_bin');
|
||||||
|
|
||||||
// Build script line
|
// Build script line
|
||||||
$frameworkPath = ModuleLoader::getModule('silverstripe/framework')->getPath();
|
$frameworkPath = ModuleLoader::getModule('silverstripe/framework')->getPath();
|
||||||
$scriptPath = sprintf("%s%scli-script.php", $frameworkPath, DIRECTORY_SEPARATOR);
|
$scriptPath = sprintf("%s%scli-script.php", $frameworkPath, DIRECTORY_SEPARATOR);
|
||||||
|
$scriptTask = "{$php} {$scriptPath} dev/tasks/{$taskName}";
|
||||||
|
|
||||||
$cmd = [
|
$cmd = "{$scriptTask} index={$indexClassEscaped} class={$class} group={$group} groups={$groups} variantstate={$statevar}";
|
||||||
$php,
|
$cmd .= " verbose=1";
|
||||||
$scriptPath,
|
$logger->info("Running '$cmd'");
|
||||||
"dev/tasks/{$taskName}",
|
|
||||||
"index={$indexClass}",
|
|
||||||
"class={$class}",
|
|
||||||
"group={$group}",
|
|
||||||
"groups={$groups}",
|
|
||||||
"variantstate={$statevar}",
|
|
||||||
"verbose=1"
|
|
||||||
];
|
|
||||||
$logger->info('Running ' . implode(' ', $cmd));
|
|
||||||
|
|
||||||
// Execute script via shell
|
// Execute script via shell
|
||||||
$process = new Process($cmd);
|
$process = new Process($cmd);
|
||||||
@ -109,7 +110,7 @@ class SolrReindexImmediateHandler extends SolrReindexBase
|
|||||||
|
|
||||||
$res = $process->getOutput();
|
$res = $process->getOutput();
|
||||||
if ($logger) {
|
if ($logger) {
|
||||||
$logger->info(preg_replace('/\r\n|\n/', '$0 ', $res ?? ''));
|
$logger->info(preg_replace('/\r\n|\n/', '$0 ', $res));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're in dev mode, commit more often for fun and profit
|
// If we're in dev mode, commit more often for fun and profit
|
||||||
|
@ -24,7 +24,7 @@ class SolrService extends SolrService_Core
|
|||||||
*/
|
*/
|
||||||
protected function coreCommand($command, $core, $params = array())
|
protected function coreCommand($command, $core, $params = array())
|
||||||
{
|
{
|
||||||
$command = strtoupper($command ?? '');
|
$command = strtoupper($command);
|
||||||
$params = array_merge($params, array('action' => $command, 'wt' => 'json'));
|
$params = array_merge($params, array('action' => $command, 'wt' => 'json'));
|
||||||
$params[$command === 'CREATE' ? 'name' : 'core'] = $core;
|
$params[$command === 'CREATE' ? 'name' : 'core'] = $core;
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ class Solr
|
|||||||
$module = ModuleLoader::getModule('silverstripe/fulltextsearch');
|
$module = ModuleLoader::getModule('silverstripe/fulltextsearch');
|
||||||
$modulePath = $module->getPath();
|
$modulePath = $module->getPath();
|
||||||
|
|
||||||
if (version_compare($version ?? '', '4', '>=')) {
|
if (version_compare($version, '4', '>=')) {
|
||||||
$versionDefaults = [
|
$versionDefaults = [
|
||||||
'service' => Solr4Service::class,
|
'service' => Solr4Service::class,
|
||||||
'extraspath' => $modulePath . '/conf/solr/4/extras/',
|
'extraspath' => $modulePath . '/conf/solr/4/extras/',
|
||||||
|
@ -89,7 +89,7 @@ abstract class SolrIndex extends SearchIndex
|
|||||||
{
|
{
|
||||||
$globalOptions = Solr::solr_options();
|
$globalOptions = Solr::solr_options();
|
||||||
$path = $this->templatesPath ? $this->templatesPath : $globalOptions['templatespath'];
|
$path = $this->templatesPath ? $this->templatesPath : $globalOptions['templatespath'];
|
||||||
return rtrim($path ?? '', '/');
|
return rtrim($path, '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -127,7 +127,7 @@ abstract class SolrIndex extends SearchIndex
|
|||||||
$indexParts[] = $indexSuffix;
|
$indexParts[] = $indexSuffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
return implode($indexParts ?? '');
|
return implode($indexParts);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTypes()
|
public function getTypes()
|
||||||
@ -256,11 +256,11 @@ abstract class SolrIndex extends SearchIndex
|
|||||||
*/
|
*/
|
||||||
protected function getNiceSuggestion($collation = '')
|
protected function getNiceSuggestion($collation = '')
|
||||||
{
|
{
|
||||||
$collationParts = explode(' ', $collation ?? '');
|
$collationParts = explode(' ', $collation);
|
||||||
|
|
||||||
// Remove advanced query params from the beginning of each collation part.
|
// Remove advanced query params from the beginning of each collation part.
|
||||||
foreach ($collationParts as $key => &$part) {
|
foreach ($collationParts as $key => &$part) {
|
||||||
$part = ltrim($part ?? '', '+');
|
$part = ltrim($part, '+');
|
||||||
}
|
}
|
||||||
|
|
||||||
return implode(' ', $collationParts);
|
return implode(' ', $collationParts);
|
||||||
@ -275,7 +275,7 @@ abstract class SolrIndex extends SearchIndex
|
|||||||
*/
|
*/
|
||||||
protected function getSuggestionQueryString($collation = '')
|
protected function getSuggestionQueryString($collation = '')
|
||||||
{
|
{
|
||||||
return str_replace(' ', '+', $this->getNiceSuggestion($collation) ?? '');
|
return str_replace(' ', '+', $this->getNiceSuggestion($collation));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -312,7 +312,7 @@ abstract class SolrIndex extends SearchIndex
|
|||||||
{
|
{
|
||||||
// Ensure that 'boost' is recorded here without being captured by solr
|
// Ensure that 'boost' is recorded here without being captured by solr
|
||||||
$boost = null;
|
$boost = null;
|
||||||
if (array_key_exists('boost', $extraOptions ?? [])) {
|
if (array_key_exists('boost', $extraOptions)) {
|
||||||
$boost = $extraOptions['boost'];
|
$boost = $extraOptions['boost'];
|
||||||
unset($extraOptions['boost']);
|
unset($extraOptions['boost']);
|
||||||
}
|
}
|
||||||
@ -515,7 +515,7 @@ abstract class SolrIndex extends SearchIndex
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check single origin
|
// Check single origin
|
||||||
return $class === $base || is_subclass_of($class, $base ?? '');
|
return $class === $base || is_subclass_of($class, $base);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function _addField($doc, $object, $field)
|
protected function _addField($doc, $object, $field)
|
||||||
@ -536,7 +536,7 @@ abstract class SolrIndex extends SearchIndex
|
|||||||
if (!$sub) {
|
if (!$sub) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$sub = gmdate('Y-m-d\TH:i:s\Z', strtotime($sub ?? ''));
|
$sub = gmdate('Y-m-d\TH:i:s\Z', strtotime($sub));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Solr requires numbers to be valid if presented, not just empty */
|
/* Solr requires numbers to be valid if presented, not just empty */
|
||||||
@ -552,7 +552,7 @@ abstract class SolrIndex extends SearchIndex
|
|||||||
if (!$value) {
|
if (!$value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$value = gmdate('Y-m-d\TH:i:s\Z', strtotime($value ?? ''));
|
$value = gmdate('Y-m-d\TH:i:s\Z', strtotime($value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Solr requires numbers to be valid if presented, not just empty */
|
/* Solr requires numbers to be valid if presented, not just empty */
|
||||||
@ -586,7 +586,7 @@ abstract class SolrIndex extends SearchIndex
|
|||||||
// Add the user-specified fields
|
// Add the user-specified fields
|
||||||
|
|
||||||
foreach ($this->getFieldsIterator() as $name => $field) {
|
foreach ($this->getFieldsIterator() as $name => $field) {
|
||||||
if ($field['base'] === $base || (is_array($field['base']) && in_array($base, $field['base'] ?? []))) {
|
if ($field['base'] === $base || (is_array($field['base']) && in_array($base, $field['base']))) {
|
||||||
$this->_addField($doc, $object, $field);
|
$this->_addField($doc, $object, $field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -607,7 +607,7 @@ abstract class SolrIndex extends SearchIndex
|
|||||||
$docs = array();
|
$docs = array();
|
||||||
|
|
||||||
foreach ($this->getClasses() as $searchclass => $options) {
|
foreach ($this->getClasses() as $searchclass => $options) {
|
||||||
if ($searchclass == $class || ($options['include_children'] && is_subclass_of($class, $searchclass ?? ''))) {
|
if ($searchclass == $class || ($options['include_children'] && is_subclass_of($class, $searchclass))) {
|
||||||
$base = DataObject::getSchema()->baseDataClass($searchclass);
|
$base = DataObject::getSchema()->baseDataClass($searchclass);
|
||||||
$docs[] = $this->_addAs($object, $base, $options);
|
$docs[] = $this->_addAs($object, $base, $options);
|
||||||
}
|
}
|
||||||
@ -619,7 +619,7 @@ abstract class SolrIndex extends SearchIndex
|
|||||||
public function canAdd($class)
|
public function canAdd($class)
|
||||||
{
|
{
|
||||||
foreach ($this->classes as $searchclass => $options) {
|
foreach ($this->classes as $searchclass => $options) {
|
||||||
if ($searchclass == $class || ($options['include_children'] && is_subclass_of($class, $searchclass ?? ''))) {
|
if ($searchclass == $class || ($options['include_children'] && is_subclass_of($class, $searchclass))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -713,7 +713,7 @@ abstract class SolrIndex extends SearchIndex
|
|||||||
|
|
||||||
// If using boosting, set the clean term separately for highlighting.
|
// If using boosting, set the clean term separately for highlighting.
|
||||||
// See https://issues.apache.org/jira/browse/SOLR-2632
|
// See https://issues.apache.org/jira/browse/SOLR-2632
|
||||||
if (array_key_exists('hl', $params ?? []) && !array_key_exists('hl.q', $params ?? [])) {
|
if (array_key_exists('hl', $params) && !array_key_exists('hl.q', $params)) {
|
||||||
$params['hl.q'] = implode(' ', $hlq);
|
$params['hl.q'] = implode(' ', $hlq);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -870,7 +870,7 @@ abstract class SolrIndex extends SearchIndex
|
|||||||
*/
|
*/
|
||||||
protected function applySearchVariants(SearchQuery $query)
|
protected function applySearchVariants(SearchQuery $query)
|
||||||
{
|
{
|
||||||
$classes = count($query->classes ?? []) ? $query->classes : $this->getClasses();
|
$classes = count($query->classes) ? $query->classes : $this->getClasses();
|
||||||
|
|
||||||
/** @var SearchVariant_Caller $variantCaller */
|
/** @var SearchVariant_Caller $variantCaller */
|
||||||
$variantCaller = SearchVariant::withCommon($classes);
|
$variantCaller = SearchVariant::withCommon($classes);
|
||||||
@ -886,7 +886,7 @@ abstract class SolrIndex extends SearchIndex
|
|||||||
*/
|
*/
|
||||||
public function sanitiseClassName($className, $replaceWith = '\\\\')
|
public function sanitiseClassName($className, $replaceWith = '\\\\')
|
||||||
{
|
{
|
||||||
return str_replace('\\', $replaceWith ?? '', $className ?? '');
|
return str_replace('\\', $replaceWith, $className);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -901,14 +901,14 @@ abstract class SolrIndex extends SearchIndex
|
|||||||
$q = array();
|
$q = array();
|
||||||
foreach ($searchQuery->search as $search) {
|
foreach ($searchQuery->search as $search) {
|
||||||
$text = $search['text'];
|
$text = $search['text'];
|
||||||
preg_match_all('/"[^"]*"|\S+/', $text ?? '', $parts);
|
preg_match_all('/"[^"]*"|\S+/', $text, $parts);
|
||||||
|
|
||||||
$fuzzy = $search['fuzzy'] ? '~' : '';
|
$fuzzy = $search['fuzzy'] ? '~' : '';
|
||||||
|
|
||||||
foreach ($parts[0] as $part) {
|
foreach ($parts[0] as $part) {
|
||||||
$fields = (isset($search['fields'])) ? $search['fields'] : array();
|
$fields = (isset($search['fields'])) ? $search['fields'] : array();
|
||||||
if (isset($search['boost'])) {
|
if (isset($search['boost'])) {
|
||||||
$fields = array_merge($fields, array_keys($search['boost'] ?? []));
|
$fields = array_merge($fields, array_keys($search['boost']));
|
||||||
}
|
}
|
||||||
if ($fields) {
|
if ($fields) {
|
||||||
$searchq = array();
|
$searchq = array();
|
||||||
@ -1014,7 +1014,7 @@ abstract class SolrIndex extends SearchIndex
|
|||||||
*/
|
*/
|
||||||
protected function getCriteriaComponent(SearchQuery $searchQuery)
|
protected function getCriteriaComponent(SearchQuery $searchQuery)
|
||||||
{
|
{
|
||||||
if (count($searchQuery->getCriteria() ?? []) === 0) {
|
if (count($searchQuery->getCriteria()) === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1095,7 +1095,7 @@ abstract class SolrIndex extends SearchIndex
|
|||||||
|
|
||||||
// Upload additional files
|
// Upload additional files
|
||||||
foreach (glob($this->getExtrasPath() . '/*') as $file) {
|
foreach (glob($this->getExtrasPath() . '/*') as $file) {
|
||||||
if (is_file($file ?? '')) {
|
if (is_file($file)) {
|
||||||
$store->uploadFile($this->getIndexName(), $file);
|
$store->uploadFile($this->getIndexName(), $file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,8 @@ class SolrConfigStore_File implements SolrConfigStore
|
|||||||
{
|
{
|
||||||
$targetDir = "{$this->local}/{$index}/conf";
|
$targetDir = "{$this->local}/{$index}/conf";
|
||||||
|
|
||||||
if (!is_dir($targetDir ?? '')) {
|
if (!is_dir($targetDir)) {
|
||||||
$worked = @mkdir($targetDir ?? '', 0770, true);
|
$worked = @mkdir($targetDir, 0770, true);
|
||||||
|
|
||||||
if (!$worked) {
|
if (!$worked) {
|
||||||
throw new \RuntimeException(
|
throw new \RuntimeException(
|
||||||
@ -36,7 +36,7 @@ class SolrConfigStore_File implements SolrConfigStore
|
|||||||
public function uploadFile($index, $file)
|
public function uploadFile($index, $file)
|
||||||
{
|
{
|
||||||
$targetDir = $this->getTargetDir($index);
|
$targetDir = $this->getTargetDir($index);
|
||||||
copy($file ?? '', $targetDir . '/' . basename($file ?? ''));
|
copy($file, $targetDir . '/' . basename($file));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function uploadString($index, $filename, $string)
|
public function uploadString($index, $filename, $string)
|
||||||
|
@ -43,7 +43,7 @@ class SolrConfigStore_Post implements SolrConfigStore
|
|||||||
*/
|
*/
|
||||||
public function uploadFile($index, $file)
|
public function uploadFile($index, $file)
|
||||||
{
|
{
|
||||||
$this->uploadString($index, basename($file ?? ''), file_get_contents($file ?? ''));
|
$this->uploadString($index, basename($file), file_get_contents($file));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -46,7 +46,7 @@ class SolrConfigStore_WebDAV implements SolrConfigStore
|
|||||||
public function uploadFile($index, $file)
|
public function uploadFile($index, $file)
|
||||||
{
|
{
|
||||||
$targetDir = $this->getTargetDir($index);
|
$targetDir = $this->getTargetDir($index);
|
||||||
WebDAV::upload_from_file($file, $targetDir . '/' . basename($file ?? ''));
|
WebDAV::upload_from_file($file, $targetDir . '/' . basename($file));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function uploadString($index, $filename, $string)
|
public function uploadString($index, $filename, $string)
|
||||||
|
@ -86,7 +86,7 @@ class Solr_Reindex extends Solr_BuildTask
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//check the indexname matches the index passed to the request
|
//check the indexname matches the index passed to the request
|
||||||
if (!strcasecmp(singleton($solrIndexClass)->getIndexName() ?? '', $index ?? '')) {
|
if (!strcasecmp(singleton($solrIndexClass)->getIndexName(), $index)) {
|
||||||
//if we match, set the correct index name and move on
|
//if we match, set the correct index name and move on
|
||||||
$index = $solrIndexClass;
|
$index = $solrIndexClass;
|
||||||
break;
|
break;
|
||||||
@ -104,7 +104,7 @@ class Solr_Reindex extends Solr_BuildTask
|
|||||||
// Run grouped batches (id % groups = group)
|
// Run grouped batches (id % groups = group)
|
||||||
$group = $request->getVar('group');
|
$group = $request->getVar('group');
|
||||||
$indexInstance = singleton($index);
|
$indexInstance = singleton($index);
|
||||||
$state = json_decode($request->getVar('variantstate') ?? '', true);
|
$state = json_decode($request->getVar('variantstate'), true);
|
||||||
|
|
||||||
$handler->runGroup($this->getLogger(), $indexInstance, $state, $class, $groups, $group);
|
$handler->runGroup($this->getLogger(), $indexInstance, $state, $class, $groups, $group);
|
||||||
return;
|
return;
|
||||||
|
@ -20,7 +20,7 @@ class SolrSearchQueryWriterBasic extends AbstractSearchQueryWriter
|
|||||||
return sprintf(
|
return sprintf(
|
||||||
'%s(%s%s%s)',
|
'%s(%s%s%s)',
|
||||||
$this->getComparisonPolarity($searchCriterion->getComparison()),
|
$this->getComparisonPolarity($searchCriterion->getComparison()),
|
||||||
addslashes($searchCriterion->getTarget() ?? ''),
|
addslashes($searchCriterion->getTarget()),
|
||||||
$this->getComparisonConjunction(),
|
$this->getComparisonConjunction(),
|
||||||
$searchCriterion->getQuoteValue($searchCriterion->getValue())
|
$searchCriterion->getQuoteValue($searchCriterion->getValue())
|
||||||
);
|
);
|
||||||
|
@ -62,7 +62,7 @@ class SolrSearchQueryWriterIn extends AbstractSearchQueryWriter
|
|||||||
|
|
||||||
$conditions[] = sprintf(
|
$conditions[] = sprintf(
|
||||||
'%s%s%s',
|
'%s%s%s',
|
||||||
addslashes($searchCriterion->getTarget() ?? ''),
|
addslashes($searchCriterion->getTarget()),
|
||||||
$this->getComparisonConjunction(),
|
$this->getComparisonConjunction(),
|
||||||
$value
|
$value
|
||||||
);
|
);
|
||||||
|
@ -21,7 +21,7 @@ class SolrSearchQueryWriterRange extends AbstractSearchQueryWriter
|
|||||||
return sprintf(
|
return sprintf(
|
||||||
'%s(%s:%s%s%s%s%s)',
|
'%s(%s:%s%s%s%s%s)',
|
||||||
$this->getComparisonPolarity($searchCriterion->getComparison()),
|
$this->getComparisonPolarity($searchCriterion->getComparison()),
|
||||||
addslashes($searchCriterion->getTarget() ?? ''),
|
addslashes($searchCriterion->getTarget()),
|
||||||
$this->getOpenComparisonContainer($searchCriterion->getComparison()),
|
$this->getOpenComparisonContainer($searchCriterion->getComparison()),
|
||||||
$this->getLeftComparison($searchCriterion),
|
$this->getLeftComparison($searchCriterion),
|
||||||
$this->getComparisonConjunction(),
|
$this->getComparisonConjunction(),
|
||||||
|
@ -18,21 +18,20 @@ class CombinationsArrayIterator implements Iterator
|
|||||||
$this->arrays = array();
|
$this->arrays = array();
|
||||||
$this->keys = array();
|
$this->keys = array();
|
||||||
|
|
||||||
$keys = array_keys($args ?? []);
|
$keys = array_keys($args);
|
||||||
$values = array_values($args ?? []);
|
$values = array_values($args);
|
||||||
|
|
||||||
foreach ($values as $i => $arg) {
|
foreach ($values as $i => $arg) {
|
||||||
if (is_array($arg) && count($arg ?? [])) {
|
if (is_array($arg) && count($arg)) {
|
||||||
$this->arrays[] = $arg;
|
$this->arrays[] = $arg;
|
||||||
$this->keys[] = $keys[$i];
|
$this->keys[] = $keys[$i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->numArrays = count($this->arrays ?? []);
|
$this->numArrays = count($this->arrays);
|
||||||
$this->rewind();
|
$this->rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[\ReturnTypeWillChange]
|
|
||||||
public function rewind()
|
public function rewind()
|
||||||
{
|
{
|
||||||
if (!$this->numArrays) {
|
if (!$this->numArrays) {
|
||||||
@ -47,13 +46,11 @@ class CombinationsArrayIterator implements Iterator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[\ReturnTypeWillChange]
|
|
||||||
public function valid()
|
public function valid()
|
||||||
{
|
{
|
||||||
return $this->isValid;
|
return $this->isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[\ReturnTypeWillChange]
|
|
||||||
public function next()
|
public function next()
|
||||||
{
|
{
|
||||||
$this->k++;
|
$this->k++;
|
||||||
@ -71,17 +68,15 @@ class CombinationsArrayIterator implements Iterator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[\ReturnTypeWillChange]
|
|
||||||
public function current()
|
public function current()
|
||||||
{
|
{
|
||||||
$res = array();
|
$res = array();
|
||||||
for ($i = 0; $i < $this->numArrays; $i++) {
|
for ($i = 0; $i < $this->numArrays; $i++) {
|
||||||
$res[$this->keys[$i]] = current($this->arrays[$i] ?? []);
|
$res[$this->keys[$i]] = current($this->arrays[$i]);
|
||||||
}
|
}
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[\ReturnTypeWillChange]
|
|
||||||
public function key()
|
public function key()
|
||||||
{
|
{
|
||||||
return $this->k;
|
return $this->k;
|
||||||
|
@ -90,7 +90,7 @@ class MonologFactory implements SearchLogFactory
|
|||||||
{
|
{
|
||||||
return Injector::inst()->createWithArgs(
|
return Injector::inst()->createWithArgs(
|
||||||
Logger::class,
|
Logger::class,
|
||||||
array(strtolower($name ?? ''))
|
array(strtolower($name))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ class MultipleArrayIterator implements Iterator
|
|||||||
|
|
||||||
$this->arrays = array();
|
$this->arrays = array();
|
||||||
foreach ($args as $arg) {
|
foreach ($args as $arg) {
|
||||||
if (is_array($arg) && count($arg ?? [])) {
|
if (is_array($arg) && count($arg)) {
|
||||||
$this->arrays[] = $arg;
|
$this->arrays[] = $arg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -22,7 +22,6 @@ class MultipleArrayIterator implements Iterator
|
|||||||
$this->rewind();
|
$this->rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[\ReturnTypeWillChange]
|
|
||||||
public function rewind()
|
public function rewind()
|
||||||
{
|
{
|
||||||
$this->active = $this->arrays;
|
$this->active = $this->arrays;
|
||||||
@ -31,19 +30,16 @@ class MultipleArrayIterator implements Iterator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[\ReturnTypeWillChange]
|
|
||||||
public function current()
|
public function current()
|
||||||
{
|
{
|
||||||
return $this->active ? current($this->active[0]) : false;
|
return $this->active ? current($this->active[0]) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[\ReturnTypeWillChange]
|
|
||||||
public function key()
|
public function key()
|
||||||
{
|
{
|
||||||
return $this->active ? key($this->active[0]) : false;
|
return $this->active ? key($this->active[0]) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[\ReturnTypeWillChange]
|
|
||||||
public function next()
|
public function next()
|
||||||
{
|
{
|
||||||
if (!$this->active) {
|
if (!$this->active) {
|
||||||
@ -58,9 +54,8 @@ class MultipleArrayIterator implements Iterator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[\ReturnTypeWillChange]
|
|
||||||
public function valid()
|
public function valid()
|
||||||
{
|
{
|
||||||
return $this->active && (current($this->active[0] ?? []) !== false);
|
return $this->active && (current($this->active[0]) !== false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,19 +17,15 @@ class WebDAV
|
|||||||
public static function exists($url)
|
public static function exists($url)
|
||||||
{
|
{
|
||||||
// WebDAV expects that checking a directory exists has a trailing slash
|
// WebDAV expects that checking a directory exists has a trailing slash
|
||||||
if (substr($url ?? '', -1) != '/') {
|
if (substr($url, -1) != '/') {
|
||||||
$url .= '/';
|
$url .= '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
$ch = self::curl_init($url, 'PROPFIND');
|
$ch = self::curl_init($url, 'PROPFIND');
|
||||||
|
|
||||||
curl_exec($ch);
|
$res = curl_exec($ch);
|
||||||
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
|
||||||
$err = curl_error($ch);
|
|
||||||
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
if ($code == 404) {
|
if ($code == 404) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -37,16 +33,15 @@ class WebDAV
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
user_error("Got error from webdav server - " . $err, E_USER_ERROR);
|
user_error("Got error from webdav server - " . $code, E_USER_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function mkdir($url)
|
public static function mkdir($url)
|
||||||
{
|
{
|
||||||
$ch = self::curl_init(rtrim($url ?? '', '/') . '/', 'MKCOL');
|
$ch = self::curl_init(rtrim($url, '/') . '/', 'MKCOL');
|
||||||
|
|
||||||
curl_exec($ch);
|
$res = curl_exec($ch);
|
||||||
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
return $code == 201;
|
return $code == 201;
|
||||||
}
|
}
|
||||||
@ -61,24 +56,22 @@ class WebDAV
|
|||||||
|
|
||||||
curl_setopt($ch, CURLOPT_INFILE, $handle);
|
curl_setopt($ch, CURLOPT_INFILE, $handle);
|
||||||
|
|
||||||
curl_exec($ch);
|
$res = curl_exec($ch);
|
||||||
fclose($handle);
|
fclose($handle);
|
||||||
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
return $code;
|
return curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function upload_from_string($string, $url)
|
public static function upload_from_string($string, $url)
|
||||||
{
|
{
|
||||||
$fh = tmpfile();
|
$fh = tmpfile();
|
||||||
fwrite($fh, $string ?? '');
|
fwrite($fh, $string);
|
||||||
fseek($fh, 0);
|
fseek($fh, 0);
|
||||||
return self::put($fh, $url);
|
return self::put($fh, $url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function upload_from_file($string, $url)
|
public static function upload_from_file($string, $url)
|
||||||
{
|
{
|
||||||
return self::put(fopen($string ?? '', 'rb'), $url);
|
return self::put(fopen($string, 'rb'), $url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ class BatchedProcessorTest extends SapphireTest
|
|||||||
$processor->addDirtyIDs(
|
$processor->addDirtyIDs(
|
||||||
BatchedProcessorTest_Object::class,
|
BatchedProcessorTest_Object::class,
|
||||||
array(array(
|
array(array(
|
||||||
'id' => $object->ID,
|
'id' => $id,
|
||||||
'state' => array(SearchVariantVersioned::class => 'Stage')
|
'state' => array(SearchVariantVersioned::class => 'Stage')
|
||||||
)),
|
)),
|
||||||
BatchedProcessorTest_Index::class
|
BatchedProcessorTest_Index::class
|
||||||
@ -133,28 +133,28 @@ class BatchedProcessorTest extends SapphireTest
|
|||||||
$this->assertEquals(9, $data->totalSteps);
|
$this->assertEquals(9, $data->totalSteps);
|
||||||
$this->assertEquals(0, $data->currentStep);
|
$this->assertEquals(0, $data->currentStep);
|
||||||
$this->assertEmpty($data->isComplete);
|
$this->assertEmpty($data->isComplete);
|
||||||
$this->assertEquals(0, count($index->getAdded() ?? []));
|
$this->assertEquals(0, count($index->getAdded()));
|
||||||
|
|
||||||
// Advance state
|
// Advance state
|
||||||
for ($pass = 1; $pass <= 8; $pass++) {
|
for ($pass = 1; $pass <= 8; $pass++) {
|
||||||
$processor->process();
|
$processor->process();
|
||||||
$data = $processor->getJobData();
|
$data = $processor->getJobData();
|
||||||
$this->assertEquals($pass, $data->currentStep);
|
$this->assertEquals($pass, $data->currentStep);
|
||||||
$this->assertEquals($pass * 5, count($index->getAdded() ?? []));
|
$this->assertEquals($pass * 5, count($index->getAdded()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last run should have two hanging items
|
// Last run should have two hanging items
|
||||||
$processor->process();
|
$processor->process();
|
||||||
$data = $processor->getJobData();
|
$data = $processor->getJobData();
|
||||||
$this->assertEquals(9, $data->currentStep);
|
$this->assertEquals(9, $data->currentStep);
|
||||||
$this->assertEquals(42, count($index->getAdded() ?? []));
|
$this->assertEquals(42, count($index->getAdded()));
|
||||||
$this->assertTrue($data->isComplete);
|
$this->assertTrue($data->isComplete);
|
||||||
|
|
||||||
// Check any additional queued jobs
|
// Check any additional queued jobs
|
||||||
$processor->afterComplete();
|
$processor->afterComplete();
|
||||||
$service = singleton(QueuedJobService::class);
|
$service = singleton(QueuedJobService::class);
|
||||||
$jobs = $service->getJobs();
|
$jobs = $service->getJobs();
|
||||||
$this->assertEquals(1, count($jobs ?? []));
|
$this->assertEquals(1, count($jobs));
|
||||||
$this->assertInstanceOf(SearchUpdateCommitJobProcessor::class, $jobs[0]['job']);
|
$this->assertInstanceOf(SearchUpdateCommitJobProcessor::class, $jobs[0]['job']);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +242,7 @@ class BatchedProcessorTest extends SapphireTest
|
|||||||
}
|
}
|
||||||
$data = $processor->getJobData();
|
$data = $processor->getJobData();
|
||||||
$this->assertEquals(8, $data->currentStep);
|
$this->assertEquals(8, $data->currentStep);
|
||||||
$this->assertEquals(42, count($index->getAdded() ?? []));
|
$this->assertEquals(42, count($index->getAdded()));
|
||||||
$this->assertTrue($data->isComplete);
|
$this->assertTrue($data->isComplete);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ class SearchVariantSubsiteTest extends SapphireTest
|
|||||||
self::$index = singleton(static::class);
|
self::$index = singleton(static::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
Config::inst()->merge(Injector::class, SearchUpdateProcessor::class, [
|
Config::inst()->update(Injector::class, SearchUpdateProcessor::class, [
|
||||||
'class' => SearchUpdateImmediateProcessor::class
|
'class' => SearchUpdateImmediateProcessor::class
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ class SolrIndexSubsitesTest extends SapphireTest
|
|||||||
$subsiteIDs = ['0'] + $this->allFixtureIDs(Subsite::class);
|
$subsiteIDs = ['0'] + $this->allFixtureIDs(Subsite::class);
|
||||||
$subsiteIDs = array_map(function ($v) {
|
$subsiteIDs = array_map(function ($v) {
|
||||||
return (string) $v;
|
return (string) $v;
|
||||||
}, $subsiteIDs ?? []);
|
}, $subsiteIDs);
|
||||||
$mockWrites = [
|
$mockWrites = [
|
||||||
'35910:File:a:0:{}' => [
|
'35910:File:a:0:{}' => [
|
||||||
'base' => File::class,
|
'base' => File::class,
|
||||||
@ -253,7 +253,7 @@ class SolrIndexSubsitesTest extends SapphireTest
|
|||||||
$tmpMockWrites = $mockWrites;
|
$tmpMockWrites = $mockWrites;
|
||||||
$variant->extractManipulationWriteState($tmpMockWrites);
|
$variant->extractManipulationWriteState($tmpMockWrites);
|
||||||
foreach ($tmpMockWrites as $mockWrite) {
|
foreach ($tmpMockWrites as $mockWrite) {
|
||||||
$this->assertCount(count($subsiteIDs ?? []), $mockWrite['statefulids']);
|
$this->assertCount(count($subsiteIDs), $mockWrite['statefulids']);
|
||||||
foreach ($mockWrite['statefulids'] as $statefulIDs) {
|
foreach ($mockWrite['statefulids'] as $statefulIDs) {
|
||||||
$this->assertContains(
|
$this->assertContains(
|
||||||
(string) $statefulIDs['state'][SearchVariantSubsites::class],
|
(string) $statefulIDs['state'][SearchVariantSubsites::class],
|
||||||
|
@ -478,7 +478,7 @@ class SolrIndexTest extends SapphireTest
|
|||||||
SolrIndexTest_MyDataObjectOne::class . $objOneA->ID,
|
SolrIndexTest_MyDataObjectOne::class . $objOneA->ID,
|
||||||
SolrIndexTest_MyDataObjectTwo::class . $objTwoA->ID
|
SolrIndexTest_MyDataObjectTwo::class . $objTwoA->ID
|
||||||
];
|
];
|
||||||
return in_array($this->createSolrDocKey($doc), $validKeys ?? []);
|
return in_array($this->createSolrDocKey($doc), $validKeys);
|
||||||
};
|
};
|
||||||
|
|
||||||
$serviceMock
|
$serviceMock
|
||||||
@ -504,7 +504,7 @@ class SolrIndexTest extends SapphireTest
|
|||||||
->method('deleteById')
|
->method('deleteById')
|
||||||
->withConsecutive(
|
->withConsecutive(
|
||||||
[$this->callback(function (string $docID) use ($pageA): bool {
|
[$this->callback(function (string $docID) use ($pageA): bool {
|
||||||
return strpos($docID ?? '', $pageA->ID . '-' . SiteTree::class) !== false;
|
return strpos($docID, $pageA->ID . '-' . SiteTree::class) !== false;
|
||||||
})]
|
})]
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -578,7 +578,7 @@ class SolrIndexTest extends SapphireTest
|
|||||||
File::class . $fileA->ID,
|
File::class . $fileA->ID,
|
||||||
SolrIndexTest_MyDataObjectOne::class . $objOneA->ID
|
SolrIndexTest_MyDataObjectOne::class . $objOneA->ID
|
||||||
];
|
];
|
||||||
return in_array($this->createSolrDocKey($doc), $validKeys ?? []);
|
return in_array($this->createSolrDocKey($doc), $validKeys);
|
||||||
};
|
};
|
||||||
|
|
||||||
$serviceMock
|
$serviceMock
|
||||||
@ -602,7 +602,7 @@ class SolrIndexTest extends SapphireTest
|
|||||||
->method('deleteById')
|
->method('deleteById')
|
||||||
->withConsecutive(
|
->withConsecutive(
|
||||||
[$this->callback(function (string $docID) use ($pageA): bool {
|
[$this->callback(function (string $docID) use ($pageA): bool {
|
||||||
return strpos($docID ?? '', $pageA->ID . '-' . SiteTree::class) !== false;
|
return strpos($docID, $pageA->ID . '-' . SiteTree::class) !== false;
|
||||||
})]
|
})]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -233,9 +233,9 @@ class SolrReindexQueuedTest extends SapphireTest
|
|||||||
|
|
||||||
// Check IDs
|
// Check IDs
|
||||||
$idMessage = $logger->filterMessages('Updated ');
|
$idMessage = $logger->filterMessages('Updated ');
|
||||||
$this->assertNotEmpty(preg_match('/^Updated (?<ids>[,\d]+)/i', $idMessage[0] ?? '', $matches));
|
$this->assertNotEmpty(preg_match('/^Updated (?<ids>[,\d]+)/i', $idMessage[0], $matches));
|
||||||
$ids = array_unique(explode(',', $matches['ids'] ?? ''));
|
$ids = array_unique(explode(',', $matches['ids']));
|
||||||
$this->assertEquals(6, count($ids ?? []));
|
$this->assertEquals(6, count($ids));
|
||||||
foreach ($ids as $id) {
|
foreach ($ids as $id) {
|
||||||
// Each id should be % 3 == 0
|
// Each id should be % 3 == 0
|
||||||
$this->assertEquals(0, $id % 3, "ID $id Should match pattern ID % 3 = 0");
|
$this->assertEquals(0, $id % 3, "ID $id Should match pattern ID % 3 = 0");
|
||||||
|
@ -250,8 +250,8 @@ class SolrReindexTest extends SapphireTest
|
|||||||
$state = array(SolrReindexTest_Variant::class => '1');
|
$state = array(SolrReindexTest_Variant::class => '1');
|
||||||
$this->getHandler()->runGroup($logger, $this->index, $state, SolrReindexTest_Item::class, 6, 2);
|
$this->getHandler()->runGroup($logger, $this->index, $state, SolrReindexTest_Item::class, 6, 2);
|
||||||
$idMessage = $logger->filterMessages('Updated ');
|
$idMessage = $logger->filterMessages('Updated ');
|
||||||
$this->assertNotEmpty(preg_match('/^Updated (?<ids>[,\d]+)/i', $idMessage[0] ?? '', $matches));
|
$this->assertNotEmpty(preg_match('/^Updated (?<ids>[,\d]+)/i', $idMessage[0], $matches));
|
||||||
$ids = array_unique(explode(',', $matches['ids'] ?? ''));
|
$ids = array_unique(explode(',', $matches['ids']));
|
||||||
|
|
||||||
// Test successful
|
// Test successful
|
||||||
$this->assertNotEmpty($logger->getMessages('Adding ' . SolrReindexTest_Item::class));
|
$this->assertNotEmpty($logger->getMessages('Adding ' . SolrReindexTest_Item::class));
|
||||||
@ -259,7 +259,7 @@ class SolrReindexTest extends SapphireTest
|
|||||||
|
|
||||||
// Test that items in this variant / group are re-indexed
|
// Test that items in this variant / group are re-indexed
|
||||||
// 120 divided into 6 groups should be 20 at least (max 21)
|
// 120 divided into 6 groups should be 20 at least (max 21)
|
||||||
$c = count($ids ?? []);
|
$c = count($ids);
|
||||||
$this->assertTrue($c === 20 || $c === 21, 'Group size is about 20');
|
$this->assertTrue($c === 20 || $c === 21, 'Group size is about 20');
|
||||||
foreach ($ids as $id) {
|
foreach ($ids as $id) {
|
||||||
// Each id should be % 6 == 2
|
// Each id should be % 6 == 2
|
||||||
@ -301,12 +301,12 @@ class SolrReindexTest extends SapphireTest
|
|||||||
// Count all ids updated
|
// Count all ids updated
|
||||||
$ids = array();
|
$ids = array();
|
||||||
foreach ($logger->filterMessages('Updated ') as $message) {
|
foreach ($logger->filterMessages('Updated ') as $message) {
|
||||||
$this->assertNotEmpty(preg_match('/^Updated (?<ids>[,\d]+)/', $message ?? '', $matches));
|
$this->assertNotEmpty(preg_match('/^Updated (?<ids>[,\d]+)/', $message, $matches));
|
||||||
$ids = array_unique(array_merge($ids, explode(',', $matches['ids'] ?? '')));
|
$ids = array_unique(array_merge($ids, explode(',', $matches['ids'])));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check ids
|
// Check ids
|
||||||
$this->assertEquals(120, count($ids ?? []));
|
$this->assertEquals(120, count($ids));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -385,7 +385,7 @@ class SolrReindexTest extends SapphireTest
|
|||||||
SolrIndexTest_MyDataObjectOne::class . $objOneA->ID,
|
SolrIndexTest_MyDataObjectOne::class . $objOneA->ID,
|
||||||
SolrIndexTest_MyDataObjectTwo::class . $objTwoA->ID
|
SolrIndexTest_MyDataObjectTwo::class . $objTwoA->ID
|
||||||
];
|
];
|
||||||
return in_array($this->createSolrDocKey($doc), $validKeys ?? []);
|
return in_array($this->createSolrDocKey($doc), $validKeys);
|
||||||
};
|
};
|
||||||
|
|
||||||
$serviceMock
|
$serviceMock
|
||||||
@ -470,7 +470,7 @@ class SolrReindexTest extends SapphireTest
|
|||||||
SolrIndexTest_MyDataObjectOne::class . $objOneA->ID,
|
SolrIndexTest_MyDataObjectOne::class . $objOneA->ID,
|
||||||
];
|
];
|
||||||
$solrDocKey = $this->createSolrDocKey($doc);
|
$solrDocKey = $this->createSolrDocKey($doc);
|
||||||
return in_array($this->createSolrDocKey($doc), $validKeys ?? []);
|
return in_array($this->createSolrDocKey($doc), $validKeys);
|
||||||
};
|
};
|
||||||
|
|
||||||
$serviceMock
|
$serviceMock
|
||||||
|
@ -49,9 +49,9 @@ class SolrReindexTest_RecordingLogger extends Logger implements TestOnly
|
|||||||
public function filterMessages($containing)
|
public function filterMessages($containing)
|
||||||
{
|
{
|
||||||
return array_values(array_filter(
|
return array_values(array_filter(
|
||||||
$this->getMessages() ?? [],
|
$this->getMessages(),
|
||||||
function ($content) use ($containing) {
|
function ($content) use ($containing) {
|
||||||
return stripos($content ?? '', $containing ?? '') !== false;
|
return stripos($content, $containing) !== false;
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -69,6 +69,6 @@ class SolrReindexTest_RecordingLogger extends Logger implements TestOnly
|
|||||||
} else {
|
} else {
|
||||||
$messages = $this->getMessages();
|
$messages = $this->getMessages();
|
||||||
}
|
}
|
||||||
return count($messages ?? []);
|
return count($messages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,7 +185,7 @@ class SolrWritersTest extends SapphireTest
|
|||||||
|
|
||||||
$index = new SolrIndexTest_FakeIndex();
|
$index = new SolrIndexTest_FakeIndex();
|
||||||
|
|
||||||
$this->assertTrue(in_array($expected, $index->getFiltersComponent($query) ?? []));
|
$this->assertTrue(in_array($expected, $index->getFiltersComponent($query)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -235,6 +235,6 @@ class SolrWritersTest extends SapphireTest
|
|||||||
|
|
||||||
$index = new SolrIndexTest_FakeIndex();
|
$index = new SolrIndexTest_FakeIndex();
|
||||||
|
|
||||||
$this->assertTrue(in_array($expected, $index->getFiltersComponent($query) ?? []));
|
$this->assertTrue(in_array($expected, $index->getFiltersComponent($query)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user