You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by ct...@apache.org on 2021/12/12 19:30:03 UTC

[solr] branch jira/solr-15556-antora updated (561a152 -> ba822ef)

This is an automated email from the ASF dual-hosted git repository.

ctargett pushed a change to branch jira/solr-15556-antora
in repository https://gitbox.apache.org/repos/asf/solr.git.


    from 561a152  Modify UI bundle location for local development; enable favicon
     add 67b1323  SOLR-15807: New LogListener class for tests to use to make assertions about what Log messages should or should not be produced by a test
     add 5b6d9db  SOLR-15590 - Start CoreContainer with Context Listener (#416)
     add 7ea2530  SOLR-13900: Reset index values on authorization rules after deleting by index (#434)
     add 52d8e2c  SOLR-15808: Remove the GITHUB_URL arg from the docker build (#425)
     add 470b7fb  SOLR-15813: Schema designer not handling  stored as a string (vs. boolean) in the config overlay (#435)
     add 46b9880  SOLR-15809 Get rid of blacklist/whitelist terminology (#424)
     add f49734e  SOLR-15825: Security UI 'hasPermission' check should check if the user has the all permission if the requested permission is not defined (#437)
     add cfc953b  SOLR-15828: AuthTool (in SolrCLI) should include the config-read, collection-admin-read, core-admin-read, and all permissions in the initial security.json (#438)
     add b144f73  SOLR-15199: Pass thru all command actions not explicitly handled by the bin/solr script, such as 'api', to the SolrCLI Java app (#441)
     add 17ac945  SOLR-15818 Fix branch_8x mention (#431)
     add c1f916d  SOLR-15826: ResourceLoader should better respect allowed paths (#439)
     add d3ea49d  SOLR-15786 (#409)
     add d172b2c  SOLR-15826 Simplify some code in SolrResourceLoader, consider PR feedback (#443)
     add 6fdbe17  SOLR-15590 Fix SSL, init order misplaced by prior commit for this ticket. (#445)
     add 417e5c1  SOLR-15747: Convert /node v2 APIs to annotations (#433)
     add 0287458  SOLR-15833 Spatial types should work with exists query (#446)
     add aa8c976  SOLR-15838: Update Solr to use released Lucene 9.0.0 (#449)
     add 28b0c2a  LUCENE-9660: add tests.neverUpToDate=true option which, by default, makes test tasks always execute. (#410)
     add 7f7a6f6  LUCENE-9660: correct help/tests.txt.
     add 10fb66f  SOLR-15832: Clean-up after publish action in Schema Designer shouldn't fail if .system collection doesn't exist (#451)
     add 84a542c  SOLR-15839: Don't mock oal.search.Sort class (why the hell was this needed?) (#452)
     add 841cbe0  SOLR-8319: Fix NPE in pivot facets, add non-Analyzed query method in FieldType
     add 82f9d47  SOLR-8319: Fix cluster usage in FacetPivot2CollectionsTest
     add fa58743  SOLR-15843 Update Log4J to 2.15 (#454)
     add b772158  Fix RPT documentation (#442)
     add 09c8a75  Update transaction log options descriptions (#383)
     add 66c76dd  SOLR-15745: Convert create-core v2 API to annotations (#450)
     new ba822ef  Merge branch 'main' into jira/solr-15556-antora

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 dev-docs/cloud-script.adoc                         |   2 +-
 dev-docs/working-between-major-versions.adoc       |  17 +-
 .../test-patch/lucene-solr-yetus-personality.sh    |   4 +-
 gradle/globals.gradle                              |   4 +-
 gradle/testing/defaults-tests.gradle               |   8 +
 gradle/validation/jar-checks.gradle                |  38 +-
 help/tests.txt                                     |  12 +-
 solr/CHANGES.txt                                   |  31 +
 solr/bin/solr                                      |  18 +-
 solr/bin/solr.cmd                                  |  48 +-
 solr/bin/solr.in.cmd                               |  10 +-
 solr/bin/solr.in.sh                                |   8 +-
 .../client/solrj/embedded/JettySolrRunner.java     |  85 +--
 .../src/java/org/apache/solr/core/NodeConfig.java  |  39 ++
 .../org/apache/solr/core/SolrResourceLoader.java   |  83 ++-
 .../solr/handler/admin/CoreAdminHandler.java       |  37 +-
 .../solr/handler/admin/HealthCheckHandler.java     |  28 +-
 .../org/apache/solr/handler/admin/InfoHandler.java |  49 +-
 .../apache/solr/handler/admin/LoggingHandler.java  |  26 +-
 .../handler/admin/PropertiesRequestHandler.java    |  20 +-
 .../solr/handler/admin/SystemInfoHandler.java      |  52 +-
 .../solr/handler/admin/ThreadDumpHandler.java      |  32 +-
 .../solr/handler/admin/api/CreateCoreAPI.java      |  78 +++
 .../solr/handler/admin/api/InvokeClassAPI.java     |  64 ++
 .../solr/handler/admin/api/NodeHealthAPI.java      |  48 ++
 .../solr/handler/admin/api/NodeLoggingAPI.java     |  49 ++
 .../solr/handler/admin/api/NodePropertiesAPI.java  |  47 ++
 .../solr/handler/admin/api/NodeSystemInfoAPI.java  |  49 ++
 .../solr/handler/admin/api/NodeThreadsAPI.java     |  47 ++
 .../handler/admin/api/OverseerOperationAPI.java    |  64 ++
 .../handler/admin/api/RejoinLeaderElectionAPI.java |  73 ++
 .../org/apache/solr/handler/api/ApiRegistrar.java  |  19 +-
 .../org/apache/solr/handler/api/V2ApiUtils.java    |   7 +
 .../handler/component/PivotFacetProcessor.java     |   4 +-
 .../solr/handler/designer/SchemaDesignerAPI.java   |  17 +-
 .../designer/SchemaDesignerConfigSetHelper.java    |   5 +-
 .../handler/designer/SchemaDesignerSettings.java   |  18 +-
 .../designer/SchemaDesignerSettingsDAO.java        |  11 +-
 .../java/org/apache/solr/request/SimpleFacets.java |   2 +-
 .../solr/schema/AbstractSpatialFieldType.java      |   9 +
 .../src/java/org/apache/solr/schema/FieldType.java |  15 +-
 .../solr/schema/ManagedIndexSchemaFactory.java     |   2 +-
 .../src/java/org/apache/solr/schema/TextField.java |   9 +
 .../src/java/org/apache/solr/schema/TrieField.java |  10 -
 .../org/apache/solr/search/JoinQParserPlugin.java  |   4 +-
 .../org/apache/solr/search/TermQParserPlugin.java  |  16 +-
 .../solr/search/facet/FacetFieldProcessor.java     |   6 +-
 .../search/facet/FacetFieldProcessorByHashDV.java  |   2 +-
 .../solr/security/AutorizationEditOperation.java   | 105 +--
 .../org/apache/solr/security/JWTAuthPlugin.java    |  20 +-
 .../apache/solr/servlet/CoreContainerProvider.java | 476 +++++++++++++
 ...ervletUtils.java => ExceptionWhileTracing.java} |  21 +-
 .../java/org/apache/solr/servlet/HttpSolrCall.java |   4 +-
 .../apache/solr/servlet/LoadAdminUiServlet.java    |   4 +-
 .../{ServletUtils.java => PathExcluder.java}       |  21 +-
 .../java/org/apache/solr/servlet/ServletUtils.java | 320 +++++++++
 ...Utils.java => SolrAuthenticationException.java} |  19 +-
 .../apache/solr/servlet/SolrDispatchFilter.java    | 746 +++++----------------
 .../src/java/org/apache/solr/util/SolrCLI.java     |  91 ++-
 .../collectionA/conf/schema.xml                    | 104 +++
 .../collectionA/conf/solrconfig.xml                |  58 ++
 .../collectionA/conf/stopwords.txt                 |  78 +++
 .../collectionB/conf/schema.xml                    | 104 +++
 .../collectionB/conf/solrconfig.xml                |  58 ++
 .../collectionB/conf/stopwords.txt                 |  82 +++
 .../org/apache/solr/cloud/SolrXmlInZkTest.java     |   3 +-
 .../org/apache/solr/core/ResourceLoaderTest.java   |  41 +-
 .../test/org/apache/solr/core/TestLazyCores.java   |   3 +-
 .../org/apache/solr/handler/TestRequestId.java     |  71 +-
 .../solr/handler/admin/V2CoresAPIMappingTest.java  | 150 +++++
 .../handler/admin/api/V2NodeAPIMappingTest.java    | 272 ++++++++
 .../component/FacetPivot2CollectionsTest.java      | 313 +++++++++
 .../handler/component/MockSortSpecBuilder.java     |   3 +-
 .../designer/TestSchemaDesignerSettingsDAO.java    |   5 +
 .../solr/schema/ExternalFileFieldSortTest.java     |   2 +
 .../apache/solr/schema/PrimitiveFieldTypeTest.java |   2 -
 .../org/apache/solr/search/TestSolr4Spatial.java   |   5 +
 .../apache/solr/search/TestSolrQueryParser.java    |  14 +-
 .../apache/solr/search/TestTermQParserPlugin.java  |  95 +++
 .../BaseTestRuleBasedAuthorizationPlugin.java      |  31 +
 .../apache/solr/security/JWTAuthPluginTest.java    |   4 +-
 .../solr/security/TestAuthorizationFramework.java  |   2 +-
 .../solr/servlet/HttpSolrCallGetCoreTest.java      |   3 +-
 .../solr/uninverting/TestFieldCacheSort.java       |  10 +-
 .../test/org/apache/solr/util/AuthToolTest.java    |   2 +-
 .../org/apache/solr/util/TestSystemIdResolver.java |   4 +-
 solr/docker/build.gradle                           |   6 +-
 solr/docker/gradle-help.txt                        |   5 -
 solr/docker/templates/Dockerfile.body.template     |   3 -
 solr/example/README.md                             |   8 +-
 solr/example/films/README.md                       |  29 +-
 solr/example/films/film_data_generator.py          | 117 ----
 solr/licenses/log4j-1.2-api-2.14.1.jar.sha1        |   1 -
 solr/licenses/log4j-1.2-api-2.15.0.jar.sha1        |   1 +
 solr/licenses/log4j-api-2.14.1.jar.sha1            |   1 -
 solr/licenses/log4j-api-2.15.0.jar.sha1            |   1 +
 solr/licenses/log4j-core-2.14.1.jar.sha1           |   1 -
 solr/licenses/log4j-core-2.15.0.jar.sha1           |   1 +
 .../log4j-layout-template-json-2.14.1.jar.sha1     |   1 -
 .../log4j-layout-template-json-2.15.0.jar.sha1     |   1 +
 solr/licenses/log4j-slf4j-impl-2.14.1.jar.sha1     |   1 -
 solr/licenses/log4j-slf4j-impl-2.15.0.jar.sha1     |   1 +
 solr/licenses/log4j-web-2.14.1.jar.sha1            |   1 -
 solr/licenses/log4j-web-2.15.0.jar.sha1            |   1 +
 solr/licenses/lucene-LICENSE-ASL.txt               | 507 ++++++++++++++
 solr/licenses/lucene-NOTICE.txt                    | 212 ++++++
 .../licenses/lucene-analysis-common-9.0.0.jar.sha1 |   1 +
 solr/licenses/lucene-analysis-icu-9.0.0.jar.sha1   |   1 +
 .../lucene-analysis-kuromoji-9.0.0.jar.sha1        |   1 +
 .../lucene-analysis-morfologik-9.0.0.jar.sha1      |   1 +
 solr/licenses/lucene-analysis-nori-9.0.0.jar.sha1  |   1 +
 .../lucene-analysis-opennlp-9.0.0.jar.sha1         |   1 +
 .../lucene-analysis-phonetic-9.0.0.jar.sha1        |   1 +
 .../lucene-analysis-smartcn-9.0.0.jar.sha1         |   1 +
 .../lucene-analysis-stempel-9.0.0.jar.sha1         |   1 +
 .../licenses/lucene-backward-codecs-9.0.0.jar.sha1 |   1 +
 solr/licenses/lucene-classification-9.0.0.jar.sha1 |   1 +
 solr/licenses/lucene-codecs-9.0.0.jar.sha1         |   1 +
 solr/licenses/lucene-core-9.0.0.jar.sha1           |   1 +
 solr/licenses/lucene-expressions-9.0.0.jar.sha1    |   1 +
 solr/licenses/lucene-grouping-9.0.0.jar.sha1       |   1 +
 solr/licenses/lucene-highlighter-9.0.0.jar.sha1    |   1 +
 solr/licenses/lucene-join-9.0.0.jar.sha1           |   1 +
 solr/licenses/lucene-memory-9.0.0.jar.sha1         |   1 +
 solr/licenses/lucene-misc-9.0.0.jar.sha1           |   1 +
 solr/licenses/lucene-queries-9.0.0.jar.sha1        |   1 +
 solr/licenses/lucene-queryparser-9.0.0.jar.sha1    |   1 +
 solr/licenses/lucene-sandbox-9.0.0.jar.sha1        |   1 +
 solr/licenses/lucene-spatial-extras-9.0.0.jar.sha1 |   1 +
 solr/licenses/lucene-spatial3d-9.0.0.jar.sha1      |   1 +
 solr/licenses/lucene-suggest-9.0.0.jar.sha1        |   1 +
 solr/licenses/lucene-test-framework-9.0.0.jar.sha1 |   1 +
 solr/licenses/spatial4j-0.7.jar.sha1               |   1 -
 solr/licenses/spatial4j-0.8.jar.sha1               |   1 +
 solr/server/etc/jetty-ssl.xml                      |   3 +
 .../pages/commits-transaction-logs.adoc            |   4 +-
 .../pages/jwt-authentication-plugin.adoc           |   4 +-
 .../deployment-guide/pages/securing-solr.adoc      |   6 +-
 .../pages/solr-control-script-reference.adoc       |  10 +
 .../modules/indexing-guide/pages/filters.adoc      |   4 +-
 .../modules/query-guide/pages/spatial-search.adoc  |   2 +-
 .../pages/major-changes-in-solr-9.adoc             |   3 +
 .../solr/client/solrj/request/CoreApiMapping.java  |  25 +-
 .../solrj/request/beans/CreateCorePayload.java     |  83 +++
 .../solrj/request/beans/InvokeClassPayload.java}   |  23 +-
 .../request/beans/OverseerOperationPayload.java}   |  25 +-
 .../beans/RejoinLeaderElectionPayload.java}        |  41 +-
 .../src/resources/apispec/cores.Commands.json      |  85 ---
 .../solrj/src/resources/apispec/node.Commands.json |  24 -
 solr/solrj/src/resources/apispec/node.Info.json    |  12 -
 solr/solrj/src/resources/apispec/node.invoke.json  |  16 -
 .../apache/solr/common/util/JsonValidatorTest.java |   2 -
 .../src/java/org/apache/solr/SolrTestCaseHS.java   |  16 +-
 .../src/java/org/apache/solr/SolrTestCaseJ4.java   |   4 +-
 .../solr/cloud/AbstractDistribZkTestBase.java      |   2 +-
 .../java/org/apache/solr/util/BaseTestHarness.java |   4 +-
 .../java/org/apache/solr/util/ErrorLogMuter.java   |   2 +
 .../org/apache/solr/util/Log4jListAppender.java    |  79 ---
 .../src/java/org/apache/solr/util/LogListener.java | 511 ++++++++++++++
 .../org/apache/solr/util/TestErrorLogMuter.java    |  86 ++-
 solr/webapp/web/WEB-INF/web.xml                    |   4 +-
 .../web/js/angular/controllers/schema-designer.js  |  10 +-
 solr/webapp/web/js/angular/controllers/security.js |   8 +-
 versions.lock                                      |  62 +-
 versions.props                                     |   4 +-
 165 files changed, 5126 insertions(+), 1637 deletions(-)
 create mode 100644 solr/core/src/java/org/apache/solr/handler/admin/api/CreateCoreAPI.java
 create mode 100644 solr/core/src/java/org/apache/solr/handler/admin/api/InvokeClassAPI.java
 create mode 100644 solr/core/src/java/org/apache/solr/handler/admin/api/NodeHealthAPI.java
 create mode 100644 solr/core/src/java/org/apache/solr/handler/admin/api/NodeLoggingAPI.java
 create mode 100644 solr/core/src/java/org/apache/solr/handler/admin/api/NodePropertiesAPI.java
 create mode 100644 solr/core/src/java/org/apache/solr/handler/admin/api/NodeSystemInfoAPI.java
 create mode 100644 solr/core/src/java/org/apache/solr/handler/admin/api/NodeThreadsAPI.java
 create mode 100644 solr/core/src/java/org/apache/solr/handler/admin/api/OverseerOperationAPI.java
 create mode 100644 solr/core/src/java/org/apache/solr/handler/admin/api/RejoinLeaderElectionAPI.java
 create mode 100644 solr/core/src/java/org/apache/solr/servlet/CoreContainerProvider.java
 copy solr/core/src/java/org/apache/solr/servlet/{ServletUtils.java => ExceptionWhileTracing.java} (55%)
 copy solr/core/src/java/org/apache/solr/servlet/{ServletUtils.java => PathExcluder.java} (55%)
 copy solr/core/src/java/org/apache/solr/servlet/{ServletUtils.java => SolrAuthenticationException.java} (55%)
 create mode 100644 solr/core/src/test-files/solr/configsets/different-stopwords/collectionA/conf/schema.xml
 create mode 100644 solr/core/src/test-files/solr/configsets/different-stopwords/collectionA/conf/solrconfig.xml
 create mode 100644 solr/core/src/test-files/solr/configsets/different-stopwords/collectionA/conf/stopwords.txt
 create mode 100644 solr/core/src/test-files/solr/configsets/different-stopwords/collectionB/conf/schema.xml
 create mode 100644 solr/core/src/test-files/solr/configsets/different-stopwords/collectionB/conf/solrconfig.xml
 create mode 100644 solr/core/src/test-files/solr/configsets/different-stopwords/collectionB/conf/stopwords.txt
 create mode 100644 solr/core/src/test/org/apache/solr/handler/admin/V2CoresAPIMappingTest.java
 create mode 100644 solr/core/src/test/org/apache/solr/handler/admin/api/V2NodeAPIMappingTest.java
 create mode 100644 solr/core/src/test/org/apache/solr/handler/component/FacetPivot2CollectionsTest.java
 create mode 100644 solr/core/src/test/org/apache/solr/search/TestTermQParserPlugin.java
 delete mode 100644 solr/example/films/film_data_generator.py
 delete mode 100644 solr/licenses/log4j-1.2-api-2.14.1.jar.sha1
 create mode 100644 solr/licenses/log4j-1.2-api-2.15.0.jar.sha1
 delete mode 100644 solr/licenses/log4j-api-2.14.1.jar.sha1
 create mode 100644 solr/licenses/log4j-api-2.15.0.jar.sha1
 delete mode 100644 solr/licenses/log4j-core-2.14.1.jar.sha1
 create mode 100644 solr/licenses/log4j-core-2.15.0.jar.sha1
 delete mode 100644 solr/licenses/log4j-layout-template-json-2.14.1.jar.sha1
 create mode 100644 solr/licenses/log4j-layout-template-json-2.15.0.jar.sha1
 delete mode 100644 solr/licenses/log4j-slf4j-impl-2.14.1.jar.sha1
 create mode 100644 solr/licenses/log4j-slf4j-impl-2.15.0.jar.sha1
 delete mode 100644 solr/licenses/log4j-web-2.14.1.jar.sha1
 create mode 100644 solr/licenses/log4j-web-2.15.0.jar.sha1
 create mode 100644 solr/licenses/lucene-LICENSE-ASL.txt
 create mode 100644 solr/licenses/lucene-NOTICE.txt
 create mode 100644 solr/licenses/lucene-analysis-common-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-analysis-icu-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-analysis-kuromoji-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-analysis-morfologik-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-analysis-nori-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-analysis-opennlp-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-analysis-phonetic-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-analysis-smartcn-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-analysis-stempel-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-backward-codecs-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-classification-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-codecs-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-core-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-expressions-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-grouping-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-highlighter-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-join-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-memory-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-misc-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-queries-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-queryparser-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-sandbox-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-spatial-extras-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-spatial3d-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-suggest-9.0.0.jar.sha1
 create mode 100644 solr/licenses/lucene-test-framework-9.0.0.jar.sha1
 delete mode 100644 solr/licenses/spatial4j-0.7.jar.sha1
 create mode 100644 solr/licenses/spatial4j-0.8.jar.sha1
 create mode 100644 solr/solrj/src/java/org/apache/solr/client/solrj/request/beans/CreateCorePayload.java
 copy solr/{core/src/java/org/apache/solr/handler/api/V2ApiUtils.java => solrj/src/java/org/apache/solr/client/solrj/request/beans/InvokeClassPayload.java} (55%)
 copy solr/{core/src/java/org/apache/solr/handler/api/V2ApiUtils.java => solrj/src/java/org/apache/solr/client/solrj/request/beans/OverseerOperationPayload.java} (55%)
 copy solr/{core/src/java/org/apache/solr/servlet/ServletUtils.java => solrj/src/java/org/apache/solr/client/solrj/request/beans/RejoinLeaderElectionPayload.java} (53%)
 delete mode 100644 solr/solrj/src/resources/apispec/cores.Commands.json
 delete mode 100644 solr/solrj/src/resources/apispec/node.Commands.json
 delete mode 100644 solr/solrj/src/resources/apispec/node.Info.json
 delete mode 100644 solr/solrj/src/resources/apispec/node.invoke.json
 delete mode 100644 solr/test-framework/src/java/org/apache/solr/util/Log4jListAppender.java
 create mode 100644 solr/test-framework/src/java/org/apache/solr/util/LogListener.java

[solr] 01/01: Merge branch 'main' into jira/solr-15556-antora

Posted by ct...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ctargett pushed a commit to branch jira/solr-15556-antora
in repository https://gitbox.apache.org/repos/asf/solr.git

commit ba822ef9e176fe7a50fb452ed5c3dea28c510186
Merge: 561a152 66c76dd
Author: Cassandra Targett <ct...@apache.org>
AuthorDate: Sun Dec 12 13:28:45 2021 -0600

    Merge branch 'main' into jira/solr-15556-antora

 dev-docs/cloud-script.adoc                         |   2 +-
 dev-docs/working-between-major-versions.adoc       |  17 +-
 .../test-patch/lucene-solr-yetus-personality.sh    |   4 +-
 gradle/globals.gradle                              |   4 +-
 gradle/testing/defaults-tests.gradle               |   8 +
 gradle/validation/jar-checks.gradle                |  38 +-
 help/tests.txt                                     |  12 +-
 solr/CHANGES.txt                                   |  31 +
 solr/bin/solr                                      |  18 +-
 solr/bin/solr.cmd                                  |  48 +-
 solr/bin/solr.in.cmd                               |  10 +-
 solr/bin/solr.in.sh                                |   8 +-
 .../client/solrj/embedded/JettySolrRunner.java     |  85 +--
 .../src/java/org/apache/solr/core/NodeConfig.java  |  39 ++
 .../org/apache/solr/core/SolrResourceLoader.java   |  83 ++-
 .../solr/handler/admin/CoreAdminHandler.java       |  37 +-
 .../solr/handler/admin/HealthCheckHandler.java     |  28 +-
 .../org/apache/solr/handler/admin/InfoHandler.java |  49 +-
 .../apache/solr/handler/admin/LoggingHandler.java  |  26 +-
 .../handler/admin/PropertiesRequestHandler.java    |  20 +-
 .../solr/handler/admin/SystemInfoHandler.java      |  52 +-
 .../solr/handler/admin/ThreadDumpHandler.java      |  32 +-
 .../solr/handler/admin/api/CreateCoreAPI.java      |  78 +++
 .../solr/handler/admin/api/InvokeClassAPI.java     |  64 ++
 .../solr/handler/admin/api/NodeHealthAPI.java      |  48 ++
 .../solr/handler/admin/api/NodeLoggingAPI.java     |  49 ++
 .../solr/handler/admin/api/NodePropertiesAPI.java  |  47 ++
 .../solr/handler/admin/api/NodeSystemInfoAPI.java  |  49 ++
 .../solr/handler/admin/api/NodeThreadsAPI.java     |  47 ++
 .../handler/admin/api/OverseerOperationAPI.java    |  64 ++
 .../handler/admin/api/RejoinLeaderElectionAPI.java |  73 ++
 .../org/apache/solr/handler/api/ApiRegistrar.java  |  19 +-
 .../org/apache/solr/handler/api/V2ApiUtils.java    |   7 +
 .../handler/component/PivotFacetProcessor.java     |   4 +-
 .../solr/handler/designer/SchemaDesignerAPI.java   |  17 +-
 .../designer/SchemaDesignerConfigSetHelper.java    |   5 +-
 .../handler/designer/SchemaDesignerSettings.java   |  18 +-
 .../designer/SchemaDesignerSettingsDAO.java        |  11 +-
 .../java/org/apache/solr/request/SimpleFacets.java |   2 +-
 .../solr/schema/AbstractSpatialFieldType.java      |   9 +
 .../src/java/org/apache/solr/schema/FieldType.java |  15 +-
 .../solr/schema/ManagedIndexSchemaFactory.java     |   2 +-
 .../src/java/org/apache/solr/schema/TextField.java |   9 +
 .../src/java/org/apache/solr/schema/TrieField.java |  10 -
 .../org/apache/solr/search/JoinQParserPlugin.java  |   4 +-
 .../org/apache/solr/search/TermQParserPlugin.java  |  16 +-
 .../solr/search/facet/FacetFieldProcessor.java     |   6 +-
 .../search/facet/FacetFieldProcessorByHashDV.java  |   2 +-
 .../solr/security/AutorizationEditOperation.java   | 105 +--
 .../org/apache/solr/security/JWTAuthPlugin.java    |  20 +-
 .../apache/solr/servlet/CoreContainerProvider.java | 476 +++++++++++++
 ...ervletUtils.java => ExceptionWhileTracing.java} |  21 +-
 .../java/org/apache/solr/servlet/HttpSolrCall.java |   4 +-
 .../apache/solr/servlet/LoadAdminUiServlet.java    |   4 +-
 .../{ServletUtils.java => PathExcluder.java}       |  21 +-
 .../java/org/apache/solr/servlet/ServletUtils.java | 320 +++++++++
 ...Utils.java => SolrAuthenticationException.java} |  19 +-
 .../apache/solr/servlet/SolrDispatchFilter.java    | 746 +++++----------------
 .../src/java/org/apache/solr/util/SolrCLI.java     |  91 ++-
 .../collectionA/conf/schema.xml                    | 104 +++
 .../collectionA/conf/solrconfig.xml                |  58 ++
 .../collectionA/conf/stopwords.txt                 |  78 +++
 .../collectionB/conf/schema.xml                    | 104 +++
 .../collectionB/conf/solrconfig.xml                |  58 ++
 .../collectionB/conf/stopwords.txt                 |  82 +++
 .../org/apache/solr/cloud/SolrXmlInZkTest.java     |   3 +-
 .../org/apache/solr/core/ResourceLoaderTest.java   |  41 +-
 .../test/org/apache/solr/core/TestLazyCores.java   |   3 +-
 .../org/apache/solr/handler/TestRequestId.java     |  71 +-
 .../solr/handler/admin/V2CoresAPIMappingTest.java  | 150 +++++
 .../handler/admin/api/V2NodeAPIMappingTest.java    | 272 ++++++++
 .../component/FacetPivot2CollectionsTest.java      | 313 +++++++++
 .../handler/component/MockSortSpecBuilder.java     |   3 +-
 .../designer/TestSchemaDesignerSettingsDAO.java    |   5 +
 .../solr/schema/ExternalFileFieldSortTest.java     |   2 +
 .../apache/solr/schema/PrimitiveFieldTypeTest.java |   2 -
 .../org/apache/solr/search/TestSolr4Spatial.java   |   5 +
 .../apache/solr/search/TestSolrQueryParser.java    |  14 +-
 .../apache/solr/search/TestTermQParserPlugin.java  |  95 +++
 .../BaseTestRuleBasedAuthorizationPlugin.java      |  31 +
 .../apache/solr/security/JWTAuthPluginTest.java    |   4 +-
 .../solr/security/TestAuthorizationFramework.java  |   2 +-
 .../solr/servlet/HttpSolrCallGetCoreTest.java      |   3 +-
 .../solr/uninverting/TestFieldCacheSort.java       |  10 +-
 .../test/org/apache/solr/util/AuthToolTest.java    |   2 +-
 .../org/apache/solr/util/TestSystemIdResolver.java |   4 +-
 solr/docker/build.gradle                           |   6 +-
 solr/docker/gradle-help.txt                        |   5 -
 solr/docker/templates/Dockerfile.body.template     |   3 -
 solr/example/README.md                             |   8 +-
 solr/example/films/README.md                       |  29 +-
 solr/example/films/film_data_generator.py          | 117 ----
 solr/licenses/log4j-1.2-api-2.14.1.jar.sha1        |   1 -
 solr/licenses/log4j-1.2-api-2.15.0.jar.sha1        |   1 +
 solr/licenses/log4j-api-2.14.1.jar.sha1            |   1 -
 solr/licenses/log4j-api-2.15.0.jar.sha1            |   1 +
 solr/licenses/log4j-core-2.14.1.jar.sha1           |   1 -
 solr/licenses/log4j-core-2.15.0.jar.sha1           |   1 +
 .../log4j-layout-template-json-2.14.1.jar.sha1     |   1 -
 .../log4j-layout-template-json-2.15.0.jar.sha1     |   1 +
 solr/licenses/log4j-slf4j-impl-2.14.1.jar.sha1     |   1 -
 solr/licenses/log4j-slf4j-impl-2.15.0.jar.sha1     |   1 +
 solr/licenses/log4j-web-2.14.1.jar.sha1            |   1 -
 solr/licenses/log4j-web-2.15.0.jar.sha1            |   1 +
 solr/licenses/lucene-LICENSE-ASL.txt               | 507 ++++++++++++++
 solr/licenses/lucene-NOTICE.txt                    | 212 ++++++
 .../licenses/lucene-analysis-common-9.0.0.jar.sha1 |   1 +
 solr/licenses/lucene-analysis-icu-9.0.0.jar.sha1   |   1 +
 .../lucene-analysis-kuromoji-9.0.0.jar.sha1        |   1 +
 .../lucene-analysis-morfologik-9.0.0.jar.sha1      |   1 +
 solr/licenses/lucene-analysis-nori-9.0.0.jar.sha1  |   1 +
 .../lucene-analysis-opennlp-9.0.0.jar.sha1         |   1 +
 .../lucene-analysis-phonetic-9.0.0.jar.sha1        |   1 +
 .../lucene-analysis-smartcn-9.0.0.jar.sha1         |   1 +
 .../lucene-analysis-stempel-9.0.0.jar.sha1         |   1 +
 .../licenses/lucene-backward-codecs-9.0.0.jar.sha1 |   1 +
 solr/licenses/lucene-classification-9.0.0.jar.sha1 |   1 +
 solr/licenses/lucene-codecs-9.0.0.jar.sha1         |   1 +
 solr/licenses/lucene-core-9.0.0.jar.sha1           |   1 +
 solr/licenses/lucene-expressions-9.0.0.jar.sha1    |   1 +
 solr/licenses/lucene-grouping-9.0.0.jar.sha1       |   1 +
 solr/licenses/lucene-highlighter-9.0.0.jar.sha1    |   1 +
 solr/licenses/lucene-join-9.0.0.jar.sha1           |   1 +
 solr/licenses/lucene-memory-9.0.0.jar.sha1         |   1 +
 solr/licenses/lucene-misc-9.0.0.jar.sha1           |   1 +
 solr/licenses/lucene-queries-9.0.0.jar.sha1        |   1 +
 solr/licenses/lucene-queryparser-9.0.0.jar.sha1    |   1 +
 solr/licenses/lucene-sandbox-9.0.0.jar.sha1        |   1 +
 solr/licenses/lucene-spatial-extras-9.0.0.jar.sha1 |   1 +
 solr/licenses/lucene-spatial3d-9.0.0.jar.sha1      |   1 +
 solr/licenses/lucene-suggest-9.0.0.jar.sha1        |   1 +
 solr/licenses/lucene-test-framework-9.0.0.jar.sha1 |   1 +
 solr/licenses/spatial4j-0.7.jar.sha1               |   1 -
 solr/licenses/spatial4j-0.8.jar.sha1               |   1 +
 solr/server/etc/jetty-ssl.xml                      |   3 +
 .../pages/commits-transaction-logs.adoc            |   4 +-
 .../pages/jwt-authentication-plugin.adoc           |   4 +-
 .../deployment-guide/pages/securing-solr.adoc      |   6 +-
 .../pages/solr-control-script-reference.adoc       |  10 +
 .../modules/indexing-guide/pages/filters.adoc      |   4 +-
 .../modules/query-guide/pages/spatial-search.adoc  |   2 +-
 .../pages/major-changes-in-solr-9.adoc             |   3 +
 .../solr/client/solrj/request/CoreApiMapping.java  |  25 +-
 .../solrj/request/beans/CreateCorePayload.java     |  83 +++
 .../solrj/request/beans/InvokeClassPayload.java}   |  23 +-
 .../request/beans/OverseerOperationPayload.java}   |  25 +-
 .../beans/RejoinLeaderElectionPayload.java}        |  41 +-
 .../src/resources/apispec/cores.Commands.json      |  85 ---
 .../solrj/src/resources/apispec/node.Commands.json |  24 -
 solr/solrj/src/resources/apispec/node.Info.json    |  12 -
 solr/solrj/src/resources/apispec/node.invoke.json  |  16 -
 .../apache/solr/common/util/JsonValidatorTest.java |   2 -
 .../src/java/org/apache/solr/SolrTestCaseHS.java   |  16 +-
 .../src/java/org/apache/solr/SolrTestCaseJ4.java   |   4 +-
 .../solr/cloud/AbstractDistribZkTestBase.java      |   2 +-
 .../java/org/apache/solr/util/BaseTestHarness.java |   4 +-
 .../java/org/apache/solr/util/ErrorLogMuter.java   |   2 +
 .../org/apache/solr/util/Log4jListAppender.java    |  79 ---
 .../src/java/org/apache/solr/util/LogListener.java | 511 ++++++++++++++
 .../org/apache/solr/util/TestErrorLogMuter.java    |  86 ++-
 solr/webapp/web/WEB-INF/web.xml                    |   4 +-
 .../web/js/angular/controllers/schema-designer.js  |  10 +-
 solr/webapp/web/js/angular/controllers/security.js |   8 +-
 versions.lock                                      |  62 +-
 versions.props                                     |   4 +-
 165 files changed, 5126 insertions(+), 1637 deletions(-)

diff --cc solr/solr-ref-guide/modules/configuration-guide/pages/commits-transaction-logs.adoc
index ea56017,0000000..da25bfc
mode 100644,000000..100644
--- a/solr/solr-ref-guide/modules/configuration-guide/pages/commits-transaction-logs.adoc
+++ b/solr/solr-ref-guide/modules/configuration-guide/pages/commits-transaction-logs.adoc
@@@ -1,322 -1,0 +1,322 @@@
 += Commits and Transaction Logs
 +// Licensed to the Apache Software Foundation (ASF) under one
 +// or more contributor license agreements.  See the NOTICE file
 +// distributed with this work for additional information
 +// regarding copyright ownership.  The ASF licenses this file
 +// to you under the Apache License, Version 2.0 (the
 +// "License"); you may not use this file except in compliance
 +// with the License.  You may obtain a copy of the License at
 +//
 +//   http://www.apache.org/licenses/LICENSE-2.0
 +//
 +// Unless required by applicable law or agreed to in writing,
 +// software distributed under the License is distributed on an
 +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 +// KIND, either express or implied.  See the License for the
 +// specific language governing permissions and limitations
 +// under the License.
 +
 +In Solr, documents are not available for searching until a "commit" updates the Lucene index files.
 +Your commit strategy will determine when document additions, deletes, or changes are available for searching.
 +A transaction log records document updates that have been received since the last "hard" commit point.
 +
 +== <updateHandler> in solrconfig.xml
 +
 +The settings in this section are configured in the `<updateHandler>` element in `solrconfig.xml` and may affect the performance of index updates.
 +These settings affect how updates are done internally.
 +
 +The `<updateHandler>` element takes a class parameter, which must be `solr.DirectUpdateHandler2`.
 +The `_default` configset included with Solr has this section defined already, but the values for many parameters discussed below likely need to be customized for your application.
 +
 +[source,xml]
 +----
 +<config>
 +  <updateHandler class="solr.DirectUpdateHandler2">
 +    ...
 +  </updateHandler>
 +</config>
 +----
 +
 +Note that `<updateHandler>` configurations do not affect the higher level configuration of xref:requesthandlers-searchcomponents.adoc[request handlers] that process client update requests.
 +
 +== Commits
 +
 +Data sent to Solr is not searchable until it has been _committed_ to the index.
 +The reason for this is that in some cases commits can be slow and they should be done in isolation from other possible commit requests to avoid overwriting data.
 +
 +=== Hard Commits vs. Soft Commits
 +
 +Solr supports two types of commits: hard commits and soft commits.
 +
 +A *hard commit* calls `fsync` on the index files to ensure they have been flushed to stable storage.
 +The current transaction log is closed and a new one is opened.
 +See the section <<Transaction Log>> below for how data is recovered in the absence of a hard commit.
 +Optionally a hard commit can also make documents visible for search, but this may not be ideal in some use cases as it is more expensive than a soft commit.
 +By default commit actions result in a hard commit of all the Lucene index files to stable storage (disk).
 +
 +A *soft commit* is faster since it only makes index changes visible and does not `fsync` index files, start a new segment, nor start a new transaction log.
 +Search collections that have NRT requirements will want to soft commit often enough to satisfy the visibility requirements of the application.
 +A softCommit may be "less expensive" than a hard commit (`openSearcher=true`), but it is not free.
 +It is recommended that this be set for as long as is reasonable given the application requirements.
 +
 +A hard commit means that, if a server crashes, Solr will know exactly where your data was stored; a soft commit means that the data is stored, but the location information isn't yet stored.
 +The tradeoff is that a soft commit gives you faster visibility because it's not waiting for background merges to finish.
 +
 +=== Explicit Commits
 +
 +When a client includes a `commit=true` parameter with an update request, this ensures that all index segments affected by the adds and deletes on an update are written to disk as soon as index updates are completed.
 +
 +If an additional parameter `softCommit=true` is specified, then Solr performs a soft commit.
 +This is an implementation of Near Real Time storage, a feature that boosts document visibility, since you don't have to wait for background merges and storage (to ZooKeeper, if using SolrCloud) to finish before moving on to something else.
 +
 +Details about using explicit commit requests during indexing are in the section xref:indexing-guide:indexing-with-update-handlers.adoc[Indexing with Update Handlers].
 +
 +For more information about Near Real Time operations, see xref:deployment-guide:solrcloud-distributed-requests.adoc#near-real-time-nrt-use-cases[Near Real Time Use Cases].
 +
 +=== Automatic Commits
 +
 +To avoid sending explicit commit commands during indexing and to provide control over when commits happen, it's possible to configure `autoCommit` parameters in `solrconfig.xml`.
 +
 +This is preferable to sending explicit commits from the indexing client as it offers much more control over your commit strategy.
 +Note that defaults are provided in `solrconfig.xml`, but they are very likely not tuned to your needs and may introduce performance problems if not tuned effectively.
 +
 +These settings control how often pending updates will be automatically pushed to the index.
 +
 +`maxDocs`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +The number of updates that have occurred since the last commit.
 +
 +`maxTime`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +The number of milliseconds since the oldest uncommitted update.
 +When sending a large batch of documents, this parameter is preferred over `maxDocs`.
 +
 +`maxSize`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +The maximum size of the transaction log (tlog) on disk, after which a hard commit is triggered.
 +This is useful when the size of documents is unknown and the intention is to restrict the size of the transaction log to reasonable size.
 ++
 +Valid values can be bytes (default with no suffix), kilobytes (if defined with a `k` suffix, as in `25k`), megabytes (`m`) or gigabytes (`g`).
 +
 +`openSearcher`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `true`
 +|===
 ++
 +Whether to open a new searcher when performing a commit.
 +If this is `false`, the commit will flush recent index changes to stable storage, but does not cause a new searcher to be opened to make those changes visible.
 +
 +If any of the `maxDocs`, `maxTime`, or `maxSize` limits are reached, Solr automatically performs a commit operation.
 +The first of these thresholds to be reached will trigger the commit.
 +
 +If the `autoCommit` tag is missing from `solrconfig.xml`, then only explicit commits will update the index.
 +The decision whether to use autoCommit or not depends on the needs of your application.
 +
 +[source,xml]
 +----
 +<autoCommit>
 +  <maxDocs>10000</maxDocs>
 +  <maxTime>30000</maxTime>
 +  <maxSize>512m</maxSize>
 +  <openSearcher>false</openSearcher>
 +</autoCommit>
 +----
 +
 +You can also specify 'soft' autoCommits with the `autoSoftCommit` tag.
 +
 +[source,xml]
 +----
 +<autoSoftCommit>
 +  <maxTime>60000</maxTime>
 +</autoSoftCommit>
 +----
 +
 +=== AutoCommit Best Practices
 +
 +Determining the best `autoCommit` settings is a tradeoff between performance and accuracy.
 +Settings that cause frequent updates will improve the accuracy of searches because new content will be searchable more quickly, but performance may suffer because of the frequent updates.
 +Less frequent updates may improve performance but it will take longer for updates to show up in queries.
 +
 +Here is an example NRT configuration for the two flavors of commit, a hard commit every 60 seconds and a soft commit every 30 seconds.
 +Note that these are _not_ the values in the examples shipped with Solr!
 +
 +[source,xml]
 +----
 +<autoCommit>
 +  <maxTime>${solr.autoCommit.maxTime:60000}</maxTime>
 +  <openSearcher>false</openSearcher>
 +</autoCommit>
 +
 +<autoSoftCommit>
 +   <maxTime>${solr.autoSoftCommit.maxTime:30000}</maxTime>
 + </autoSoftCommit>
 +----
 +
 +TIP: These parameters can be overridden at run time by defining Java "system variables", for example specifying ``-Dsolr.autoCommit.maxTime=15000` would override the hard commit interval with a value of 15 seconds.
 +
 +The choices for `autoCommit` (with `openSearcher=false`) and `autoSoftCommit` have different consequences.
 +In the event of un-graceful shutdown, it can take up to the time specified in `autoCommit` for Solr to replay the uncommitted documents from the transaction log.
 +
 +The time chosen for `autoSoftCommit` determines the maximum time after a document is sent to Solr before it becomes searchable and does not affect the transaction log.
 +
 +Choose as long an interval as your application can tolerate for this value, often 15-60 seconds is reasonable, or even longer depending on the requirements.
 +In situations where the time is set to a very short interval (say 1 second), consider disabling your caches (queryResultCache and filterCache especially) as they will have little utility.
 +
 +TIP: For extremely high bulk indexing, especially for the initial load if there is no searching, consider turning off `autoSoftCommit` by specifying a value of `-1` for the maxTime parameter.
 +
 +=== Commit Within a Time Period
 +
 +An alternative to `autoCommit` is to use `commitWithin`, which can be defined when making the update request to Solr (i.e., when pushing documents), or in an update request handler.
 +
 +The `commitWithin` settings allow forcing document commits to happen in a defined time period.
 +This is used most frequently with xref:deployment-guide:solrcloud-distributed-requests.adoc#near-real-time-nrt-use-cases[Near Real Time use cases], and for that reason the default is to perform a soft commit.
 +This does not, however, replicate new documents to follower servers in a user-managed cluster.
 +If that's a requirement for your implementation, you can force a hard commit by adding a parameter, as in this example:
 +
 +[source,xml]
 +----
 +<commitWithin>
 +  <softCommit>false</softCommit>
 +</commitWithin>
 +----
 +
 +With this configuration, when you call `commitWithin` as part of your update message, it will automatically perform a hard commit every time.
 +
 +
 +== Transaction Log
 +
 +Transaction logs (tlogs) are a "rolling window" of updates since the last hard commit.
 +The current transaction log is closed and a new one opened each time any variety of hard commit occurs.
 +Soft commits have no effect on the transaction log.
 +
 +When tlogs are enabled, documents being added to the index are written to the tlog before the indexing call returns to the client.
 +In the event of an un-graceful shutdown (power loss, JVM crash, `kill -9`, etc.) any documents written to the tlog but not yet committed with a hard commit when Solr was stopped are replayed on startup.
 +Therefore the data is not lost.
 +
 +When Solr is shut down gracefully (using the `bin/solr stop` command) Solr will close the tlog file and index segments so no replay will be necessary on startup.
 +
 +One point of confusion is how much data is contained in a transaction log.
 +A tlog does not contain all documents, only the ones since the last hard commit.
 +Older transaction log files are deleted when no longer needed.
 +
 +WARNING: Implicit in the above is that transaction logs will grow forever if hard commits are disabled.
 +Therefore it is important that hard commits be enabled when indexing.
 +
 +=== Transaction Log Configuration
 +
 +Transaction logs are required for all SolrCloud clusters, as well as the xref:realtime-get.adoc[] feature.
 +It is configured in the `updateHandler` section of `solrconfig.xml`.
 +
 +Transaction logs are configured in `solrconfig.xml`, in a section like the following:
 +
 +[source,xml]
 +----
 +<updateLog>
 +  <str name="dir">${solr.ulog.dir:}</str>
 +</updateLog>
 +----
 +
 +The only required parameter is:
 +
 +`dir`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The location of the transaction log.
 +In Solr's default `solrconfig.xml` files, this is defined as `${solr.ulog.dir:}`.
 ++
 +As shown in the default value, the location of the transaction log can be anywhere as long as it is defined in `solrconfig.xml` and write- and read-able by Solr.
 +
 +There are three additional expert-level configuration settings which affect indexing performance and how far a replica can fall behind on updates before it must enter into full recovery.
 +These settings would primarily impact SolrCloud cluster configurations:
 +
 +`numRecordsToKeep`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `100`
 +|===
 ++
- The number of update records to keep per log.
++The minimum number of update records to keep across all the transaction log files.
 +
 +`maxNumLogsToKeep`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `10`
 +|===
 ++
- The maximum number of logs keep.
++The maximum number of transaction log files to keep.
 +
 +`numVersionBuckets`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `65336`
 +|===
 ++
 +The number of buckets used to keep track of maximum version values when checking for re-ordered updates.
 +Increase this value to reduce the cost of synchronizing access to version buckets during high-volume indexing.
 +This requires `(8 bytes (long) * numVersionBuckets)` of heap space per Solr core.
 +
 +An example, to be included under `<updateHandler>` in `solrconfig.xml`, employing the above advanced settings:
 +
 +[source,xml]
 +----
 +<updateLog>
 +  <str name="dir">${solr.ulog.dir:}</str>
 +  <int name="numRecordsToKeep">500</int>
 +  <int name="maxNumLogsToKeep">20</int>
 +  <int name="numVersionBuckets">65536</int>
 +</updateLog>
 +----
 +
 +== Event Listeners
 +
 +The UpdateHandler section is also where update-related event listeners can be configured.
 +These can be triggered to occur after any commit (`event="postCommit"`) or only after optimize commands (`event="postOptimize"`).
 +
 +Users can write custom update event listener classes in Solr plugins.
 +As of Solr 7.1, `RunExecutableListener` was removed for security reasons.
 +
 +== Other <updateHandler> Options
 +
 +In some cases complex updates (such as spatial/shape) may take very long time to complete.
 +In the default configuration other updates that fall into the same internal version bucket will wait indefinitely.
 +Eventually these outstanding requests may pile up and lead to thread exhaustion and possibly to OutOfMemory errors.
 +
 +The parameter `versionBucketLockTimeoutMs` helps to prevent that by specifying a timeout for long-running update requests.
 +If this limit is reached the update will fail but it won't block forever all other updates.
 +
 +There is a memory cost associated with this setting.
 +Values greater than the default of `0` (unlimited timeout) cause Solr to use a different internal implementation of the version bucket, which increases memory consumption from ~1.5MB to ~6.8MB per Solr core.
 +
 +An example of specifying this option under `<config>` section of `solrconfig.xml`:
 +
 +[source,xml]
 +----
 +<updateHandler class="solr.DirectUpdateHandler2">
 +  ...
 +  <int name="versionBucketLockTimeoutMs">10000</int>
 +</updateHandler>
 +----
diff --cc solr/solr-ref-guide/modules/deployment-guide/pages/jwt-authentication-plugin.adoc
index a1d3451,0000000..4e720e4
mode 100644,000000..100644
--- a/solr/solr-ref-guide/modules/deployment-guide/pages/jwt-authentication-plugin.adoc
+++ b/solr/solr-ref-guide/modules/deployment-guide/pages/jwt-authentication-plugin.adoc
@@@ -1,269 -1,0 +1,269 @@@
 += JWT Authentication Plugin
 +// Licensed to the Apache Software Foundation (ASF) under one
 +// or more contributor license agreements.  See the NOTICE file
 +// distributed with this work for additional information
 +// regarding copyright ownership.  The ASF licenses this file
 +// to you under the Apache License, Version 2.0 (the
 +// "License"); you may not use this file except in compliance
 +// with the License.  You may obtain a copy of the License at
 +//
 +//   http://www.apache.org/licenses/LICENSE-2.0
 +//
 +// Unless required by applicable law or agreed to in writing,
 +// software distributed under the License is distributed on an
 +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 +// KIND, either express or implied.  See the License for the
 +// specific language governing permissions and limitations
 +// under the License.
 +
 +Solr can support https://en.wikipedia.org/wiki/JSON_Web_Token[JSON Web Token] (JWT) based Bearer authentication with the use of the JWTAuthPlugin.
 +
 +This allows Solr to assert that a user is already authenticated with an external https://en.wikipedia.org/wiki/Identity_provider[Identity Provider] by validating that the JWT formatted https://en.wikipedia.org/wiki/Access_token[access token] is digitally signed by the Identity Provider.
 +The typical use case is to integrate Solr with an https://en.wikipedia.org/wiki/OpenID_Connect[OpenID Connect] enabled IdP.
 +
 +== Enable JWT Authentication
 +
 +To use JWT Bearer authentication, the `security.json` file must have an `authentication` part which defines the class being used for authentication along with configuration parameters.
 +
 +The simplest possible `security.json` for registering the plugin without configuration is:
 +
 +[source,json]
 +----
 +{
 +  "authentication": {
 +    "class":"solr.JWTAuthPlugin",
 +    "blockUnknown":"false"
 +  }
 +}
 +----
 +
 +The plugin will by default require a valid JWT token for all traffic.
 +
 +If the `blockUnknown` property is set to `false` as in the above example, it is possible to start configuring the plugin using unauthenticated REST API calls, which is further described in section <<Editing JWT Authentication Plugin Configuration>>.
 +
 +== Configuration Parameters
 +
 +//*TODO*: standard is not to put parameters in tables but use labeled lists instead
 +[%header,format=csv,separator=;,cols="25%,50%,25%"]
 +|===
 +Key                  ; Description                                             ; Default
 +blockUnknown         ; Set to `false` to if you need to perform configuration through REST API or if you use an Authorization Plugin and only want certain paths protected. By default all requests will require a token  ; `true`
 +realm                ; Name of the authentication realm to echo back in HTTP 401 responses. Will also be displayed in Admin UI login page ; 'solr-jwt'
 +scope                ; Whitespace separated list of valid scopes. If configured, the JWT access token MUST contain a `scope` claim with at least one of the listed scopes. Example: `solr:read solr:admin` ;
 +requireIss           ; Fails requests that lacks an `iss` (issuer) claim                          ; `true`
 +requireExp           ; Fails requests that lacks an `exp` (expiry time) claim                     ; `true`
- algWhitelist         ; JSON array with algorithms to accept: `HS256`, `HS384`, `HS512`, `RS256`, `RS384`, `RS512`, `ES256`, `ES384`, `ES512`, `PS256`, `PS384`, `PS512`, `none  ; Default is to allow all algorithms
++algAllowlist         ; JSON array with algorithms to accept: `HS256`, `HS384`, `HS512`, `RS256`, `RS384`, `RS512`, `ES256`, `ES384`, `ES512`, `PS256`, `PS384`, `PS512`, `none  ; Default is to allow all algorithms
 +jwkCacheDur          ; Duration of JWK cache in seconds                        ; `3600` (1 hour)
 +principalClaim       ; What claim id to pull principal from                    ; `sub`
 +rolesClaim           ; What claim id to pull user roles from. The claim must then either contain a space separated list of roles or a JSON array. The roles can then be used to define fine-grained access in an Authorization plugin       ; By default the scopes from `scope` claim are passed on as user roles
 +claimsMatch          ; JSON object of claims (key) that must match a regular expression (value). Example: `{ "foo" : "A|B" }` will require the `foo` claim to be either "A" or "B". ;
 +adminUiScope         ; Define what scope is requested when logging in from Admin UI ; If not defined, the first scope from `scope` parameter is used
 +redirectUris         ; Valid location(s) for redirect after external authentication. Takes a string or array of strings. Must be the base URL of Solr, e.g., https://solr1.example.com:8983/solr/ and must match the list of redirect URIs registered with the Identity Provider beforehand. ; Defaults to empty list, i.e., any node is assumed to be a valid redirect target.
 +trustedCerts         ; One or more X.509 SSL certificates in plaintext PEM or PKCS#7 formats, that should be trusted when talking to IdPs. Newlines must be replaced with `\n`. See paragraph <<Trusting the IdP server>> for more about its usage. ; Defaults to Java truststore
 +trustedCertsFile     ; Path to a file of type PEM, DER or PKCS#7, containing one or more X.509 SSL certificates that should be trusted when talking to IdPs. See paragraph <<Trusting the IdP server>> for more about its usage. ; Defaults to Java truststore
 +issuers              ; List of issuers (Identity providers) to  support. See section <<issuer-configuration,Issuer configuration>> for configuration syntax ;
 +|===
 +
 +=== Issuer Configuration
 +
 +This plugin supports one or more token issuers (IdPs).
 +Issuers are configured as a list of JSON objects under the `issuers` configuration key.
 +The first issuer in the list is the "Primary Issuer", which is the one used for logging in to the Admin UI.
 +
 +[%header,format=csv,separator=;,cols="25%,50%,25%"]
 +|===
 +Key                  ; Description                                             ; Default
 +name                 ; A unique name of the issuer. Used to manipulate list through API. ;
 +wellKnownUrl         ; URL to an https://openid.net/specs/openid-connect-discovery-1_0.html[OpenID Connect Discovery] endpoint ;
 +clientId             ; Client identifier for use with OpenID Connect. Required to authenticate with Admin UI. Needed for primary issuer only ;
 +jwksUrl              ; A URL to a https://tools.ietf.org/html/rfc7517#section-5[JWKs] endpoint. Must use https protocol. Optionally an array of URLs in which case all public keys from all URLs will be consulted when validating signatures. ; Auto configured if `wellKnownUrl` is provided
 +jwk                  ; As an alternative to `jwksUrl` you may provide a static JSON object containing the public key(s) of the issuer. The format is either JWK or JWK Set, see https://tools.ietf.org/html/rfc7517#appendix-A[RFC7517] for examples. ;
 +iss                  ; Unique issuer id as configured on the IdP. Incoming tokens must have a matching `iss` claim. Also used to resolve issuer when multiple issuers configured.      ; Auto configured if `wellKnownUrl` is provided
 +aud                  ; Validates that the `aud` (audience) claim equals this string      ; Uses `clientId` if configured
 +authorizationEndpoint; The URL for the Id Provider's authorization endpoint ; Auto configured if `wellKnownUrl` is provided
 +|===
 +
 +TIP: For backwards compatibility, all the configuration keys for the primary issuer may be configured as top-level keys, except `name`.
 +
 +== More Configuration Examples
 +=== With JWKS URL
 +To start enforcing authentication for all users, requiring a valid JWT in the `Authorization` header, you need to configure the plugin with one or more https://tools.ietf.org/html/rfc7517[JSON Web Key]s (JWK).
 +This is a JSON document containing the key used to sign/encrypt the JWT.
 +It could be a symmetric or asymmetric key.
 +The JWK can either be fetched (and cached) from an external HTTPS endpoint or specified directly in `security.json`.
 +Below is an example of the former:
 +
 +[source,json]
 +----
 +{
 +  "authentication": {
 +    "class": "solr.JWTAuthPlugin",
 +    "jwksUrl": "https://my.key.server/jwk.json"
 +  }
 +}
 +----
 +
 +=== With Admin UI Support
 +This example shows configuration using https://openid.net/specs/openid-connect-discovery-1_0.html[OpenID Connect Discovery] with a well-known URI for automatic configuration of many common settings, including ability to use the Admin UI with an OpenID Connect enabled Identity Provider.
 +
 +[source,json]
 +----
 +{
 +  "authentication": {
 +    "class": "solr.JWTAuthPlugin",
 +    "wellKnownUrl": "https://idp.example.com/.well-known/openid-configuration",
 +    "clientId": "xyz",
 +    "redirectUris": "https://my.solr.server:8983/solr/"
 +  }
 +}
 +----
 +
 +In this case, `jwksUrl`, `iss`, and `authorizationEndpoint` will be automatically configured from the fetched configuration.
 +
 +=== Complex Example
 +Let's look at a more complex configuration, this time with two issuers configured, where one uses a static embedded JWK:
 +
 +[source,json]
 +----
 +{
 +  "authentication": {
 +    "class": "solr.JWTAuthPlugin", <1>
 +    "blockUnknown": true, <2>
 +    "principalClaim": "solruid", <3>
 +    "claimsMatch": { "foo" : "A|B", "dept" : "IT" }, <4>
 +    "scope": "solr:read solr:write solr:admin", <5>
-     "algWhitelist" : [ "RS256", "RS384", "RS512" ], <6>
++    "algAllowlist" : [ "RS256", "RS384", "RS512" ], <6>
 +    "issuers": [ <7>
 +      {
 +        "name": "example1-static", <8>
 +        "jwk": { <9>
 +          "e": "AQAB",
 +          "kid": "k1",
 +          "kty": "RSA",
 +          "n": "3ZF6w....vjbCXxw"
 +        },
 +        "clientId": "solr-client-12345", <10>
 +        "iss": "https://example.com/idp", <11>
 +        "aud": "https://example.com/solr" <12>
 +      },
 +      {
 +        "name": "example2",
 +        "wellKnownUrl": "https://example2.com/.well-known/oidc", <13>
 +        "aud": "https://example2.com/solr"
 +      }
 +    ],
 +    "trustedCertsFile": "/path/to/certsFile.pem" <14>
 +  }
 +}
 +----
 +
 +Let's comment on this config:
 +
 +<1> Plugin class
 +<2> Make sure to block anyone without a valid token (this is also the default)
 +<3> Fetch the user id from another claim than the default `sub`
 +<4> Require that the `roles` claim is one of "A" or "B" and that the `dept` claim is "IT"
 +<5> Require one of the scopes `solr:read`, `solr:write` or `solr:admin`
 +<6> Only accept RSA algorithms for signatures
 +<7> Array of issuer configurations
 +<8> Each issuer object should have a unique name
 +<9> Here we pass the JWK inline instead of referring to a URL with `jwksUrl`
 +<10> Set the client id registered with Identity Provider
 +<11> Configure the issuer id. Will be used for validating tokens.
 +A token's 'iss' claim must match one of the configured issuer IDs.
 +<12> Configure the audience claim.
 +A token's 'aud' claim must match 'aud' for one of the configured issuers.
 +<13> This issuer is auto-configured through discovery, so 'iss' and JWK settings are not required
 +<14> Provides SSL certificate(s) to trust IdP https communication.
 +
 +=== Using non-SSL URLs
 +In production environments you should always use SSL protected HTTPS connections, otherwise you open yourself up to attacks.
 +However, in development, it may be useful to use regular HTTP URLs, and bypass the security check that Solr performs.
 +To support this you can set the environment variable `-Dsolr.auth.jwt.allowOutboundHttp=true` at startup.
 +
 +=== Trusting the IdP server
 +All communication with the Oauth2 server (IdP) is done over HTTPS.
 +By default, Java's built-in TrustStore is used.
 +However, by configuring one of the options `trustedCertsFile` or `trustedCerts`, the plugin will *instead* trust the set of certificates provided, not any certificate signed by a root CA.
 +This is both more secure and also lets you trust self-signed certificates.
 +It also has the benefit of working even if Solr is not started in SSL mode.
 +
 +Please configure either the `trustedCerts` or `trustedCertsFile` option.
 +Configuring both will cause an error.
 +
 +=== Multiple Authentication Schemes
 +
 +Solr provides the xref:basic-authentication-plugin.adoc#combining-basic-authentication-with-other-schemes[MultiAuthPlugin] to support multiple authentication schemes based on the `Authorization` header.
 +This allows you to configure Solr to delegate user management and authentication to an OIDC provider using the `JWTAuthPlugin`,
 +but also allow a small set of service accounts to use `Basic` authentication when using OIDC is not supported or practical.
 +
 +== Editing JWT Authentication Plugin Configuration
 +
 +All properties mentioned above can be set or changed using the xref:basic-authentication-plugin.adoc#editing-basic-authentication-plugin-configuration[Authentication API].
 +You can thus start with a simple configuration with only `class` and `blockUnknown=false` configured and then configure the rest using the API.
 +
 +=== Set a Configuration Property
 +
 +Set properties for the authentication plugin.
 +Each of the configuration keys in the table above can be used as parameter keys for the `set-property` command.
 +
 +Example:
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#jwt-v1set-property]
 +====
 +[.tab-label]*V1 API*
 +
 +[source,bash]
 +----
 +curl http://localhost:8983/solr/admin/authentication -H 'Content-type:application/json' -H 'Authorization: Bearer xxx.yyy.zzz' -d '{"set-property": {"blockUnknown":true, "wellKnownUrl": "https://example.com/.well-knwon/openid-configuration", "scope": "solr:read solr:write"}}'
 +----
 +====
 +
 +[example.tab-pane#jwt-v2set-property]
 +====
 +[.tab-label]*V2 API*
 +
 +[source,bash]
 +----
 +curl http://localhost:8983/api/cluster/security/authentication -H 'Content-type:application/json' -H 'Authorization: Bearer xxx.yyy.zzz' -d -d '{"set-property": {"blockUnknown":true, "wellKnownUrl": "https://example.com/.well-knwon/openid-configuration", "scope": "solr:read solr:write"}}'
 +----
 +====
 +--
 +
 +Insert a valid JWT access token in compact serialization format (`xxx.yyy.zzz` above) to authenticate with Solr once the plugin is active, or leave `blockUnknown=false` until configuration is complete and then switch it to `true` to start enforcing.
 +
 +NOTE: There is currently no support for adding multiple token issuers though REST API, but you can configure one issuer through the API by using the 'issuer' properties as top-level properties.
 +
 +== Using Clients with JWT Auth
 +
 +[#jwt-soljr]
 +=== SolrJ
 +
 +SolrJ does not currently support supplying JWT tokens per request.
 +
 +[#jwt-curl]
 +=== cURL
 +
 +To authenticate with Solr when using the cURL utility, supply a valid JWT access token in an `Authorization` header, as follows (replace xxxxxx.xxxxxx.xxxxxx with your JWT compact token):
 +
 +[source,bash]
 +----
 +curl -H "Authorization: Bearer xxxxxx.xxxxxx.xxxxxx" http://localhost:8983/solr/admin/info/system
 +----
 +
 +=== Admin UI
 +
 +When this plugin is enabled, users will be redirected to a login page in the Admin UI once they attempt to do a restricted action.
 +The page has a button that users will click and be redirected to the Identity Provider's login page.
 +
 +If more than one issuer (IdP) is configured, the first in the list will be used for Admin UI.
 +Once authenticated, the user will be redirected back to Solr Admin UI to the last known location.
 +The session will last as long as the JWT token expiry time and is valid for one Solr server only.
 +That means you have to login again when navigating to another Solr node.
 +There is also a logout menu in the left column where user can explicitly log out.
 +
 +== Using the Solr Control Script with JWT Auth
 +
 +The control script (`bin/solr`) does not currently support JWT Auth.
diff --cc solr/solr-ref-guide/modules/deployment-guide/pages/securing-solr.adoc
index 0ced3b8,0000000..c244947
mode 100644,000000..100644
--- a/solr/solr-ref-guide/modules/deployment-guide/pages/securing-solr.adoc
+++ b/solr/solr-ref-guide/modules/deployment-guide/pages/securing-solr.adoc
@@@ -1,123 -1,0 +1,123 @@@
 += Securing Solr
 +:page-children: authentication-and-authorization-plugins, \
 +    audit-logging, \
 +    enabling-ssl, \
 +    zookeeper-access-control, \
 +    security-ui
 +// Licensed to the Apache Software Foundation (ASF) under one
 +// or more contributor license agreements.  See the NOTICE file
 +// distributed with this work for additional information
 +// regarding copyright ownership.  The ASF licenses this file
 +// to you under the Apache License, Version 2.0 (the
 +// "License"); you may not use this file except in compliance
 +// with the License.  You may obtain a copy of the License at
 +//
 +//   http://www.apache.org/licenses/LICENSE-2.0
 +//
 +// Unless required by applicable law or agreed to in writing,
 +// software distributed under the License is distributed on an
 +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 +// KIND, either express or implied.  See the License for the
 +// specific language governing permissions and limitations
 +// under the License.
 +
 +[WARNING]
 +====
 +No Solr API, including the Admin UI, is designed to be exposed to non-trusted parties.
 +Tune your firewall so that only trusted computers and people are allowed access.
 +Because of this, the project will not regard e.g., Admin UI XSS issues as security vulnerabilities.
 +However, we still ask you to report such issues in JIRA.
 +====
 +
 +When planning how to secure Solr, you should consider which of the available features or approaches are right for you:
 +
 +== Encryption with TLS (SSL) Certificates
 +
 +Encrypting traffic to/from Solr and between Solr nodes prevents sensitive data to be leaked out on the network.
 +TLS is also normally a requirement to prevent credential sniffing when using Authentication.
 +
 +See the section xref:enabling-ssl.adoc[] for details.
 +
 +== Authentication and Authorization
 +
 +Use the xref:security-ui.adoc[] screen in the Admin UI to manage users, roles, and permissions.
 +
 +See section xref:authentication-and-authorization-plugins.adoc[] to learn how to work with the `security.json` file.
 +
 +[#securing-solr-auth-plugins]
 +=== Authentication Plugins
 +
 +Authentication makes sure you know the identity of your users.
 +The authentication plugins that ship with Solr are:
 +
 +// tag::list-of-authentication-plugins[]
 +[width=100%,cols="1,1",frame=none,grid=none,stripes=none]
 +|===
 +| xref:basic-authentication-plugin.adoc[]
 +| xref:kerberos-authentication-plugin.adoc[]
 +| xref:jwt-authentication-plugin.adoc[]
 +| xref:cert-authentication-plugin.adoc[]
 +| xref:hadoop-authentication-plugin.adoc[]
 +|
 +|===
 +// end::list-of-authentication-plugins[]
 +
 +=== Authorization Plugins
 +
 +Authorization makes sure that only users with the necessary roles/permissions can access any given resource.
 +The authorization plugins that ship with Solr are:
 +
 +// tag::list-of-authorization-plugins[]
 +[width=100%,cols="1,1",frame=none,grid=none,stripes=none]
 +|===
 +| xref:rule-based-authorization-plugin.adoc[]
 +| xref:rule-based-authorization-plugin.adoc[External Role Rule-Based Authorization Plugin]
 +|===
 +// end::list-of-authorization-plugins[]
 +
 +== Audit Logging
 +
 +Audit logging will record an audit trail of incoming reqests to your cluster, such as users being denied access to admin APIs.
 +Learn more about audit logging and how to implement an audit logger plugin in the section xref:audit-logging.adoc[].
 +
 +== Request Logging
 +
 +Solr can optionally log every incoming HTTP(s) request in the standard https://en.wikipedia.org/wiki/Common_Log_Format[`NCSA format`].
 +You can enable request logging by setting `SOLR_REQUESTLOG_ENABLED=true` via environment variable or in `solr.in.sh`/`solr.in.cmd`.
 +
 +== IP Access Control
 +
- Restrict network access to specific hosts, by setting `SOLR_IP_WHITELIST`/`SOLR_IP_BLACKLIST` via environment variables or in `solr.in.sh`/`solr.in.cmd`.
++Restrict network access to specific hosts, by setting `SOLR_IP_ALLOWLIST`/`SOLR_IP_DENYLIST` via environment variables or in `solr.in.sh`/`solr.in.cmd`.
 +
 +[source,bash]
 +----
 +# Allow IPv4/IPv6 localhost, the 192.168.0.x IPv4 network, and 2000:123:4:5:: IPv6 network.
- SOLR_IP_WHITELIST="127.0.0.1, [::1], 192.168.0.0/24, [2000:123:4:5::]/64"
++SOLR_IP_ALLOWLIST="127.0.0.1, [::1], 192.168.0.0/24, [2000:123:4:5::]/64"
 +# Explicitly deny access to two problematic hosts.
- SOLR_IP_BLACKLIST="192.168.0.3, 192.168.0.4"
++SOLR_IP_DENYLIST="192.168.0.3, 192.168.0.4"
 +----
 +
 +== Securing ZooKeeper Traffic
 +
 +ZooKeeper is a central and important part of a SolrCloud cluster and understanding how to secure
 +its content is covered in the section xref:zookeeper-access-control.adoc[].
 +
 +== Network Configuration
 +
 +// tag::security-network-binding-1[]
 +Administrators should consider their security setup carefully as an important step in moving to production.
 +Solr provides a number of features out of the box to meet the security needs of users: authentication and authorization can be configured using a range of security plugins, privacy can be bolstered by enabling SSL/TLS, and (in SolrCloud) ZooKeeper data can be protected with ACL rules to prevent unauthorized reads and writes.
 +
 +Even if these measures or others are taken, it is strongly recommended that Solr always be protected by a firewall.
 +Solr is not designed to be exposed on the open internet.
 +
 +It is also strongly recommended that Solr listen to only those network interfaces that are strictly required.
 +To prevent administrators from unintentionally exposing Solr more broadly, Solr only listens on the loopback interface ("127.0.0.1") by default.
 +Most deployments will need to change this value to something less restrictive so that it can be reached from other boxes.
 +This can be done by setting a `SOLR_JETTY_HOST` value in your environment's "include script" (`solr.in.sh` or `solr.in.cmd`):
 +
 +[source,bash]
 + ----
 + SOLR_JETTY_HOST="0.0.0.0"
 + ----
 +// end::security-network-binding-1[]
diff --cc solr/solr-ref-guide/modules/deployment-guide/pages/solr-control-script-reference.adoc
index 5b07182,0000000..49655d2
mode 100644,000000..100644
--- a/solr/solr-ref-guide/modules/deployment-guide/pages/solr-control-script-reference.adoc
+++ b/solr/solr-ref-guide/modules/deployment-guide/pages/solr-control-script-reference.adoc
@@@ -1,1470 -1,0 +1,1480 @@@
 += Solr Control Script Reference
 +// Licensed to the Apache Software Foundation (ASF) under one
 +// or more contributor license agreements.  See the NOTICE file
 +// distributed with this work for additional information
 +// regarding copyright ownership.  The ASF licenses this file
 +// to you under the Apache License, Version 2.0 (the
 +// "License"); you may not use this file except in compliance
 +// with the License.  You may obtain a copy of the License at
 +//
 +//   http://www.apache.org/licenses/LICENSE-2.0
 +//
 +// Unless required by applicable law or agreed to in writing,
 +// software distributed under the License is distributed on an
 +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 +// KIND, either express or implied.  See the License for the
 +// specific language governing permissions and limitations
 +// under the License.
 +
 +Solr includes a script known as "`bin/solr`" that allows you to perform many common operations on your Solr installation or cluster.
 +
 +You can start and stop Solr, create and delete collections or cores, perform operations on ZooKeeper and check the status of Solr and configured shards.
 +
 +You can find the script in the `bin/` directory of your Solr installation.
 +The `bin/solr` script makes Solr easier to work with by providing simple commands and options to quickly accomplish common goals.
 +
 +More examples of `bin/solr` in use are available throughout this Guide, but particularly in the sections xref:installing-solr.adoc#starting-solr[Starting Solr] and xref:getting-started:tutorial-solrcloud.adoc[].
 +
 +== Starting and Stopping
 +
 +=== Start and Restart
 +
 +The `start` command starts Solr.
 +The `restart` command allows you to restart Solr while it is already running or if it has been stopped already.
 +
 +The `start` and `restart` commands have several options to allow you to run in SolrCloud mode, use an example configuration set, start with a hostname or port that is not the default and point to a local ZooKeeper ensemble.
 +
 +`bin/solr start [options]`
 +
 +`bin/solr start -help`
 +
 +`bin/solr restart [options]`
 +
 +`bin/solr restart -help`
 +
 +When using the `restart` command, you must pass all of the parameters you initially passed when you started Solr.
 +Behind the scenes, a stop request is initiated, so Solr will be stopped before being started again.
 +If no nodes are already running, restart will skip the step to stop and proceed to starting Solr.
 +
 +==== Start Parameters
 +
 +The `bin/solr` script provides many options to allow you to customize the server in common ways, such as changing the listening port.
 +However, most of the defaults are adequate for most Solr installations, especially when just getting started.
 +
 +`-a "<string>"`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +Start Solr with additional JVM parameters, such as those starting with `-X`.
 +If you are passing JVM parameters that begin with `-D`, you can omit the `-a` option.
 ++
 +*Example*:
 ++
 +[source,bash]
 +bin/solr start -a "-Xdebug -Xrunjdwp:transport=dt_socket, server=y,suspend=n,address=1044"
 +
 +`-cloud` or `-c`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +Start Solr in SolrCloud mode, which will also launch the embedded ZooKeeper instance included with Solr.
 ++
 +This option can be shortened to simply `-c`.
 ++
 +If you are already running a ZooKeeper ensemble that you want to use instead of the embedded (single-node) ZooKeeper, you should also either specify `ZK_HOST` in `solr.in.sh`/`solr.in.cmd` (see xref:zookeeper-ensemble.adoc#updating-solr-include-files[Updating Solr Include Files]) or pass the `-z` parameter.
 ++
 +For more details, see the section <<SolrCloud Mode>> below.
 ++
 +*Example*: `bin/solr start -c`
 +
 +`-d <dir>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `server/`
 +|===
 ++
 +Define a server directory, defaults to `server` (as in, `$SOLR_HOME/server`).
 +It is uncommon to override this option.
 +When running multiple instances of Solr on the same host, it is more common to use the same server directory for each instance and use a unique Solr home directory using the `-s` option.
 ++
 +*Example*: `bin/solr start -d newServerDir`
 +
 +`-e <name>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +Start Solr with an example configuration.
 +These examples are provided to help you get started faster with Solr generally, or just try a specific feature.
 ++
 +The available options are:
 +
 +* `cloud`
 +* `techproducts`
 +* `schemaless`
++* `films`
 ++
 +See the section <<Running with Example Configurations>> below for more details on the example configurations.
 ++
 +*Example*: `bin/solr start -e schemaless`
 +
 +`-f`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +Start Solr in the foreground.
 +You cannot use this option when running examples with the `-e` option.
 ++
 +*Example*: `bin/solr start -f`
 +
 +`-h <hostname>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `localhost`
 +|===
 ++
 +Start Solr with the defined hostname.
 +If this is not specified, `localhost` is assumed.
 ++
 +*Example*: `bin/solr start -h search.mysolr.com`
 +
 +`-m <memory>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +Start Solr with the defined value as the min (`-Xms`) and max (`-Xmx`) heap size for the JVM.
 ++
 +*Example*: `bin/solr start -m 1g`
 +
 +`-noprompt`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +Start Solr and suppress any prompts that may be seen with another option.
 +This would have the side effect of accepting all defaults implicitly.
 ++
 +For example, when using the "cloud" example, an interactive session guides you through several options for your SolrCloud cluster.
 +If you want to accept all of the defaults, you can simply add the `-noprompt` option to your request.
 ++
 +*Example*: `bin/solr start -e cloud -noprompt`
 +
 +`-p <port>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `8983`
 +|===
 ++
 +Start Solr on the defined port.
 +If this is not specified, `8983` will be used.
 ++
 +*Example*: `bin/solr start -p 8655`
 +
 +`-s <dir>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `server/solr`
 +|===
 ++
 +Sets the `solr.solr.home` system property.
 +Solr will create core directories under this directory.
 +This allows you to run multiple Solr instances on the same host while reusing the same server directory set using the `-d` parameter.
 ++
 +If set, the specified directory should contain a `solr.xml` file, unless `solr.xml` exists in ZooKeeper.
 ++
 +This parameter is ignored when running examples (`-e`), as the `solr.solr.home` depends on which example is run.
 ++
 +*Example*: `bin/solr start -s newHome`
 +
 +`-v`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +Be more verbose.
 +This changes the logging level of Log4j from `INFO` to `DEBUG`, having the same effect as if you edited `log4j2.xml`.
 ++
 +*Example*: `bin/solr start -f -v`
 +
 +`-q`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +Be more quiet.
 +This changes the logging level of Log4j from `INFO` to `WARN`, having the same effect as if you edited `log4j2.xml`.
 +This can be useful in a production setting where you want to limit logging to warnings and errors.
 ++
 +*Example*: `bin/solr start -f -q`
 +
 +`-V`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +Start Solr with verbose messages from the start script.
 ++
 +*Example*: `bin/solr start -V`
 +
 +`-z <zkHost>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: _see description_
 +|===
 ++
 +Start Solr with the defined ZooKeeper connection string.
 ++
 +This option is only used with the `-c` option, to start Solr in SolrCloud mode.
 +If `ZK_HOST` is not specified in `solr.in.sh`/`solr.in.cmd` and this option is not provided, Solr will start the embedded ZooKeeper instance and use that instance for SolrCloud operations.
 ++
 +*Example*: `bin/solr start -c -z server1:2181,server2:2181`
 +
 +`-force`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +If attempting to start Solr as the root user, the script will exit with a warning that running Solr as "root" can cause problems.
 +It is possible to override this warning with the `-force` parameter.
 ++
 +*Example*: `sudo bin/solr start -force`
 +
 +To emphasize how the default settings work take a moment to understand that the following commands are equivalent:
 +
 +`bin/solr start`
 +
 +`bin/solr start -h localhost -p 8983 -d server -s solr -m 512m`
 +
 +It is not necessary to define all of the options when starting if the defaults are fine for your needs.
 +
 +==== Setting Java System Properties
 +
 +The `bin/solr` script will pass any additional parameters that begin with `-D` to the JVM, which allows you to set arbitrary Java system properties.
 +
 +For example, to set the auto soft-commit frequency to 3 seconds, you can do:
 +
 +`bin/solr start -Dsolr.autoSoftCommit.maxTime=3000`
 +
 +==== SolrCloud Mode
 +
 +The `-c` and `-cloud` options are equivalent:
 +
 +`bin/solr start -c`
 +
 +`bin/solr start -cloud`
 +
 +If you specify a ZooKeeper connection string, such as `-z 192.168.1.4:2181`, then Solr will connect to ZooKeeper and join the cluster.
 +
 +NOTE: If you have defined `ZK_HOST` in `solr.in.sh`/`solr.in.cmd` (see xref:zookeeper-ensemble.adoc#updating-solr-include-files,Updating Solr Include Files>>) you can omit `-z <zk host string>` from all `bin/solr` commands.
 +
 +When starting Solr in SolrCloud mode, if you do not define `ZK_HOST` in `solr.in.sh`/`solr.in.cmd` nor specify the `-z` option, then Solr will launch an embedded ZooKeeper server listening on the Solr port + 1000.
 +For example, if Solr is running on port 8983, then the embedded ZooKeeper will listen on port 9983.
 +
 +[IMPORTANT]
 +====
 +If your ZooKeeper connection string uses a chroot, such as `localhost:2181/solr`, then you need to create the /solr znode before launching SolrCloud using the `bin/solr` script.
 ++
 +To do this use the `mkroot` command outlined below, for example: `bin/solr zk mkroot /solr -z 192.168.1.4:2181`
 +====
 +
 +When starting in SolrCloud mode, the interactive script session will prompt you to choose a configset to use.
 +
 +For more information about starting Solr in SolrCloud mode, see also the section xref:getting-started:tutorial-solrcloud.adoc[].
 +
 +==== Running with Example Configurations
 +
 +`bin/solr start -e <name>`
 +
 +The example configurations allow you to get started quickly with a configuration that mirrors what you hope to accomplish with Solr.
 +
 +Each example launches Solr with a managed schema, which allows use of the xref:indexing-guide:schema-api.adoc[] to make schema edits, but does not allow manual editing of a Schema file.
 +
 +If you would prefer to manually modify a `schema.xml` file directly, you can change this default as described in the section xref:configuration-guide:schema-factory.adoc[].
 +
 +Unless otherwise noted in the descriptions below, the examples do not enable SolrCloud nor xref:indexing-guide:schemaless-mode.adoc[].
 +
 +The following examples are provided:
 +
 +* *cloud*: This example starts a 1-4 node SolrCloud cluster on a single machine.
 +When chosen, an interactive session will start to guide you through options to select the initial configset to use, the number of nodes for your example cluster, the ports to use, and name of the collection to be created.
 ++
 +When using this example, you can choose from any of the available configsets found in `$SOLR_HOME/server/solr/configsets`.
 +
 +* *techproducts*: This example starts a single-node Solr instance with a schema designed for the sample documents included in the `$SOLR_HOME/example/exampledocs` directory.
 ++
 +The configset used can be found in `$SOLR_HOME/server/solr/configsets/sample_techproducts_configs`.
+++
++The data used can be found in `$SOLR_HOME/example/exampledocs/`.
 +
 +* *schemaless*: This example starts a single-node Solr instance using a managed schema, as described in the section xref:configuration-guide:schema-factory.adoc[], and provides a very minimal pre-defined schema.
 +Solr will run in xref:indexing-guide:schemaless-mode.adoc[] with this configuration, where Solr will create fields in the schema on the fly and will guess field types used in incoming documents.
 ++
 +The configset used can be found in `$SOLR_HOME/server/solr/configsets/_default`.
 +
++* *films*: This example starts a single-node Solr instance using a managed schema, as described in the section <<schema-factory.adoc#,Schema Factory Definition in SolrConfig>>, and then uses the Schema API to create some custom fields.
++Solr will run in <<schemaless-mode.adoc#,Schemaless Mode>> with this configuration, where Solr will create fields in the schema on the fly and will guess field types used in incoming documents as well.  It then loads some sample film data.
+++
++The configset used can be found in `$SOLR_HOME/server/solr/configsets/_default`.
+++
++The film data used can be found in `$SOLR_HOME/example/films/films.json`.
++
 +[IMPORTANT]
 +====
 +The run in-foreground option (`-f`) is not compatible with the `-e` option since the script needs to perform additional tasks after starting the Solr server.
 +====
 +
 +=== Stop
 +
 +The `stop` command sends a STOP request to a running Solr node, which allows it to shutdown gracefully.
 +The command will wait up to 180 seconds for Solr to stop gracefully and then will forcefully kill the process (`kill -9`).
 +
 +`bin/solr stop [options]`
 +
 +`bin/solr stop -help`
 +
 +==== Stop Parameters
 +
 +`-p <port>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +Stop Solr running on the given port.
 +If you are running more than one instance, or are running in SolrCloud mode, you either need to specify the ports in separate requests or use the `-all` option.
 ++
 +*Example*: `bin/solr stop -p 8983`
 +
 +`-all`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +Stop all running Solr instances that have a valid PID.
 ++
 +*Example*: `bin/solr stop -all`
 +
 +`-k <key>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +Stop key used to protect from stopping Solr inadvertently; default is "solrrocks".
 ++
 +*Example*: `bin/solr stop -k solrrocks`
 +
 +
 +== System Information
 +
 +=== Version
 +
 +The `version` command simply returns the version of Solr currently installed and immediately exists.
 +
 +[source,bash]
 +----
 +$ bin/solr version
 +X.Y.0
 +----
 +
 +=== Status
 +
 +The `status` command displays basic JSON-formatted information for any Solr nodes found running on the local system.
 +
 +The `status` command uses the `SOLR_PID_DIR` environment variable to locate Solr process ID files to find running Solr instances, which defaults to the `bin` directory.
 +
 +`bin/solr status`
 +
 +The output will include a status of each node of the cluster, as in this example:
 +
 +[source,plain]
 +----
 +Found 2 Solr nodes:
 +
 +Solr process 39920 running on port 7574
 +{
 +  "solr_home":"/Applications/Solr/example/cloud/node2/solr/",
 +  "version":"X.Y.0",
 +  "startTime":"2015-02-10T17:19:54.739Z",
 +  "uptime":"1 days, 23 hours, 55 minutes, 48 seconds",
 +  "memory":"77.2 MB (%15.7) of 490.7 MB",
 +  "cloud":{
 +    "ZooKeeper":"localhost:9865",
 +    "liveNodes":"2",
 +    "collections":"2"}}
 +
 +Solr process 39827 running on port 8865
 +{
 +  "solr_home":"/Applications/Solr/example/cloud/node1/solr/",
 +  "version":"X.Y.0",
 +  "startTime":"2015-02-10T17:19:49.057Z",
 +  "uptime":"1 days, 23 hours, 55 minutes, 54 seconds",
 +  "memory":"94.2 MB (%19.2) of 490.7 MB",
 +  "cloud":{
 +    "ZooKeeper":"localhost:9865",
 +    "liveNodes":"2",
 +    "collections":"2"}}
 +----
 +
 +=== Assert
 +
 +The `assert` command sanity checks common issues with Solr installations.
 +These include checking the ownership/existence of particular directories, and ensuring Solr is available on the expected URL.
 +The command can either output a specified error message, or change its exit code to indicate errors.
 +
 +As an example:
 +
 +[source,bash]
 +$ bin/solr assert --exists /opt/bin/solr
 +
 +Results in the output below:
 +
 +[source,plain]
 +ERROR: Directory /opt/bin/solr does not exist.
 +
 +Use `bin/solr assert -help` for a full list of options.
 +
 +=== Healthcheck
 +
 +The `healthcheck` command generates a JSON-formatted health report for a collection when running in SolrCloud mode.
 +The health report provides information about the state of every replica for all shards in a collection, including the number of committed documents and its current state.
 +
 +`bin/solr healthcheck [options]`
 +
 +`bin/solr healthcheck -help`
 +
 +==== Healthcheck Parameters
 +
 +`-c <collection>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 + Name of the collection to run a healthcheck against.
 ++
 +*Example*: `bin/solr healthcheck -c gettingstarted`
 +
 +`-z <zkhost>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `localhost:9983`
 +|===
 ++
 +ZooKeeper connection string.
 +If you are running Solr on a port other than 8983, you will have to specify the ZooKeeper connection string.
 +By default, this will be the Solr port + 1000.
 +This parameter is unnecessary if `ZK_HOST` is defined in `solr.in.sh` or `solr.in.cmd`.
 ++
 +*Example*: `bin/solr healthcheck -z localhost:2181`
 +
 +Below is an example healthcheck request and response using a non-standard ZooKeeper connect string, with 2 nodes running:
 +
 +`$ bin/solr healthcheck -c gettingstarted -z localhost:9865`
 +
 +[source,json]
 +----
 +{
 +  "collection":"gettingstarted",
 +  "status":"healthy",
 +  "numDocs":0,
 +  "numShards":2,
 +  "shards":[
 +    {
 +      "shard":"shard1",
 +      "status":"healthy",
 +      "replicas":[
 +        {
 +          "name":"core_node1",
 +          "url":"http://10.0.1.10:8865/solr/gettingstarted_shard1_replica2/",
 +          "numDocs":0,
 +          "status":"active",
 +          "uptime":"2 days, 1 hours, 18 minutes, 48 seconds",
 +          "memory":"25.6 MB (%5.2) of 490.7 MB",
 +          "leader":true},
 +        {
 +          "name":"core_node4",
 +          "url":"http://10.0.1.10:7574/solr/gettingstarted_shard1_replica1/",
 +          "numDocs":0,
 +          "status":"active",
 +          "uptime":"2 days, 1 hours, 18 minutes, 42 seconds",
 +          "memory":"95.3 MB (%19.4) of 490.7 MB"}]},
 +    {
 +      "shard":"shard2",
 +      "status":"healthy",
 +      "replicas":[
 +        {
 +          "name":"core_node2",
 +          "url":"http://10.0.1.10:8865/solr/gettingstarted_shard2_replica2/",
 +          "numDocs":0,
 +          "status":"active",
 +          "uptime":"2 days, 1 hours, 18 minutes, 48 seconds",
 +          "memory":"25.8 MB (%5.3) of 490.7 MB"},
 +        {
 +          "name":"core_node3",
 +          "url":"http://10.0.1.10:7574/solr/gettingstarted_shard2_replica1/",
 +          "numDocs":0,
 +          "status":"active",
 +          "uptime":"2 days, 1 hours, 18 minutes, 42 seconds",
 +          "memory":"95.4 MB (%19.4) of 490.7 MB",
 +          "leader":true}]}]}
 +----
 +
 +== Collections and Cores
 +
 +The `bin/solr` script can also help you create new collections or cores, or delete collections or cores.
 +
 +=== Create a Core or Collection
 +
 +The `create` command detects the mode that Solr is running in and creates either a core or collection depending on the mode.
 +When running with SolrCloud, a collection would be created.
 +When running a user-managed cluster or a single-node installation, a core would be created.
 +
 +`bin/solr create [options]`
 +
 +`bin/solr create -help`
 +
 +==== Create Core or Collection Parameters
 +
 +`-c <name>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +Name of the core or collection to create.
 ++
 +*Example*: `bin/solr create -c mycollection`
 +
 +`-d <confdir>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `_default`
 +|===
 ++
 +The configuration directory.
 ++
 +See the section <<Configuration Directories and SolrCloud>> below for more details about this option when running in SolrCloud mode.
 ++
 +*Example*: `bin/solr create -d _default`
 +
 +`-n <configName>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: _see description_
 +|===
 ++
 +The configuration name.
 +This defaults to the same name as the core or collection.
 ++
 +*Example*: `bin/solr create -n basic`
 +
 +`-p <port>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: _see description_
 +|===
 ++
 +The port of a local Solr instance to send the create command to.
 +By default the script tries to detect the port by looking for running Solr instances.
 ++
 +This option is useful if you are running multiple Solr instances on the same host, thus requiring you to be specific about which instance to create the core in.
 ++
 +*Example*: `bin/solr create -p 8983`
 +
 +`-s <shards>` or `-shards`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `1`
 +|===
 ++
 +Number of shards to split a collection into.
 +Only applies when Solr is running in SolrCloud mode.
 ++
 +*Example*: `bin/solr create -s 2`
 +
 +`-rf <replicas>` or `-replicationFactor`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `1`
 +|===
 ++
 +Number of copies of each document in the collection.
 +The default is `1` (no replication).
 ++
 +*Example*: `bin/solr create -rf 2`
 +
 +`-force`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +If attempting to run create as "root" user, the script will exit with a warning that running Solr or actions against Solr as "root" can cause problems.
 +It is possible to override this warning with the -force parameter.
 ++
 +*Example*: `bin/solr create -c foo -force`
 +
 +==== Configuration Directories and SolrCloud
 +
 +Before creating a collection in SolrCloud, the configuration directory used by the collection must be uploaded to ZooKeeper.
 +The `create` command supports several use cases for how collections and configuration directories work.
 +The main decision you need to make is whether a configuration directory in ZooKeeper should be shared across multiple collections.
 +
 +Let's work through a few examples to illustrate how configuration directories work in SolrCloud.
 +
 +First, if you don't provide the `-d` or `-n` options, then the default configuration (`$SOLR_HOME/server/solr/configsets/_default/conf`) is uploaded to ZooKeeper using the same name as the collection.
 +
 +For example, the following command will result in the `_default` configuration being uploaded to `/configs/contacts` in ZooKeeper: `bin/solr create -c contacts`.
 +
 +If you create another collection with `bin/solr create -c contacts2`, then another copy of the `_default` directory will be uploaded to ZooKeeper under `/configs/contacts2`.
 +
 +Any changes you make to the configuration for the contacts collection will not affect the `contacts2` collection.
 +Put simply, the default behavior creates a unique copy of the configuration directory for each collection you create.
 +
 +You can override the name given to the configuration directory in ZooKeeper by using the `-n` option.
 +For instance, the command `bin/solr create -c logs -d _default -n basic` will upload the `server/solr/configsets/_default/conf` directory to ZooKeeper as `/configs/basic`.
 +
 +Notice that we used the `-d` option to specify a different configuration than the default.
 +Solr provides several built-in configurations under `server/solr/configsets`.
 +However you can also provide the path to your own configuration directory using the `-d` option.
 +For instance, the command `bin/solr create -c mycoll -d /tmp/myconfigs`, will upload `/tmp/myconfigs` into ZooKeeper under `/configs/mycoll`.
 +
 +To reiterate, the configuration directory is named after the collection unless you override it using the `-n` option.
 +
 +Other collections can share the same configuration by specifying the name of the shared configuration using the `-n` option.
 +For instance, the following command will create a new collection that shares the basic configuration created previously: `bin/solr create -c logs2 -n basic`.
 +
 +==== Data-driven Schema and Shared Configurations
 +
 +The `_default` schema can mutate as data is indexed, since it has schemaless functionality (i.e., data-driven changes to the schema).
 +Consequently, we recommend that you do not share data-driven configurations between collections unless you are certain that all collections should inherit the changes made when indexing data into one of the collections.
 +
 +You can turn off schemaless functionality for a collection with the following command, assuming the collection name is `mycollection`.
 +
 +[source,bash]
 +$ bin/solr config -c mycollection -p 8983 -action set-user-property -property update.autoCreateFields -value false
 +
 +See also the section <<Set or Unset Configuration Properties>>.
 +
 +=== Delete Core or Collection
 +
 +The `delete` command detects the mode that Solr is running in and then deletes the specified core (user-managed or single-node) or collection (SolrCloud) as appropriate.
 +
 +`bin/solr delete [options]`
 +
 +`bin/solr delete -help`
 +
 +If running in SolrCloud mode, the `delete` command checks if the configuration directory used by the collection you are deleting is being used by other collections.
 +If not, then the configuration directory is also deleted from ZooKeeper.
 +
 +For example, if you created a collection with `bin/solr create -c contacts`, then the delete command `bin/solr delete -c contacts` will check to see if the `/configs/contacts` configuration directory is being used by any other collections.
 +If not, then the `/configs/contacts` directory is removed from ZooKeeper.
 +
 +==== Delete Core or Collection Parameters
 +
 +`-c <name>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +Name of the core or collection to delete.
 ++
 +*Example*: `bin/solr delete -c mycoll`
 +
 +`-deleteConfig`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `true`
 +|===
 ++
 +Whether or not the configuration directory should also be deleted from ZooKeeper.
 ++
 +If the configuration directory is being used by another collection, then it will not be deleted even if you pass `-deleteConfig` as `true`.
 ++
 +*Example*: `bin/solr delete -deleteConfig false`
 +
 +`-p <port>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: _see description_
 +|===
 ++
 +The port of a local Solr instance to send the delete command to.
 +By default the script tries to detect the port by looking for running Solr instances.
 ++
 +This option is useful if you are running multiple Solr instances on the same host, thus requiring you to be specific about which instance to delete the core from.
 ++
 +*Example*: `bin/solr delete -p 8983`
 +
 +== Authentication
 +
 +The `bin/solr` script allows enabling or disabling Basic Authentication, allowing you to configure authentication from the command line.
 +
 +Currently, this script only enables Basic Authentication, and is only available when using SolrCloud mode.
 +
 +=== Enabling Basic Authentication
 +
 +The command `bin/solr auth enable` configures Solr to use Basic Authentication when accessing the User Interface, using `bin/solr` and any API requests.
 +
 +TIP: For more information about Solr's authentication plugins, see the section xref:securing-solr.adoc[].
 +For more information on Basic Authentication support specifically, see the section xref:basic-authentication-plugin.adoc[].
 +
 +The `bin/solr auth enable` command makes several changes to enable Basic Authentication:
 +
 +* Creates a `security.json` file and uploads it to ZooKeeper.
 +The `security.json` file will look similar to:
 ++
 +[source,json]
 +----
 +{
 +  "authentication":{
 +   "blockUnknown": false,
 +   "class":"solr.BasicAuthPlugin",
 +   "credentials":{"user":"vgGVo69YJeUg/O6AcFiowWsdyOUdqfQvOLsrpIPMCzk= 7iTnaKOWe+Uj5ZfGoKKK2G6hrcF10h6xezMQK+LBvpI="}
 +  },
 +  "authorization":{
 +   "class":"solr.RuleBasedAuthorizationPlugin",
 +   "permissions":[
 + {"name":"security-edit", "role":"admin"},
 + {"name":"collection-admin-edit", "role":"admin"},
 + {"name":"core-admin-edit", "role":"admin"}
 +   ],
 +   "user-role":{"user":"admin"}
 +  }
 +}
 +----
 +* Adds two lines to `bin/solr.in.sh` or `bin\solr.in.cmd` to set the authentication type, and the path to `basicAuth.conf`:
 ++
 +[source,subs="attributes"]
 +----
 +# The following lines added by ./solr for enabling BasicAuth
 +SOLR_AUTH_TYPE="basic"
 +SOLR_AUTHENTICATION_OPTS="-Dsolr.httpclient.config=/path/to/solr-{solr-docs-version}.0/server/solr/basicAuth.conf"
 +----
 +* Creates the file `server/solr/basicAuth.conf` to store the credential information that is used with `bin/solr` commands.
 +
 +The command takes the following parameters:
 +
 +`-credentials`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +The username and password in the format of `username:password` of the initial user.
 ++
 +If you prefer not to pass the username and password as an argument to the script, you can choose the `-prompt` option.
 +Either `-credentials` or `-prompt` *must* be specified.
 +
 +`-prompt`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +If prompt is preferred, pass `true` as a parameter to request the script to prompt the user to enter a username and password.
 ++
 +Either `-credentials` or `-prompt` *must* be specified.
 +
 +`-blockUnknown`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `true`
 +|===
 ++
 +When `true`, blocks all unauthenticated users from accessing Solr.
 +When `false`, unauthenticated users will still be able to access Solr, but only for operations not explicitly requiring a user role in the Authorization plugin configuration.
 +
 +`-updateIncludeFileOnly`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `false`
 +|===
 ++
 +When `true`, only the settings in `bin/solr.in.sh` or `bin\solr.in.cmd` will be updated, and `security.json` will not be created.
 +
 +`-z`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +Defines the ZooKeeper connect string.
 +This is useful if you want to enable authentication before all your Solr nodes have come up.
 +Unnecessary if `ZK_HOST` is defined in `solr.in.sh` or `solr.in.cmd`.
 +
 +`-d`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `$SOLR_HOME/server`
 +|===
 ++
 +Defines the Solr server directory, by default `$SOLR_HOME/server`.
 +It is not common to need to override the default, and is only needed if you have customized the `$SOLR_HOME` directory path.
 +
 +`-s`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `server/solr`
 +|===
 ++
 +Defines the location of `solr.solr.home`, which by default is `server/solr`.
 +If you have multiple instances of Solr on the same host, or if you have customized the `$SOLR_HOME` directory path, you likely need to define this.
 +
 +=== Disabling Basic Authentication
 +
 +You can disable Basic Authentication with `bin/solr auth disable`.
 +
 +If the `-updateIncludeFileOnly` option is set to *true*, then only the settings in `bin/solr.in.sh` or `bin\solr.in.cmd` will be updated, and `security.json` will not be removed.
 +
 +If the `-updateIncludeFileOnly` option is set to *false*, then the settings in `bin/solr.in.sh` or `bin\solr.in.cmd` will be updated, and `security.json` will be removed.
 +However, the `basicAuth.conf` file is not removed with either option.
 +
 +== Set or Unset Configuration Properties
 +
 +The `bin/solr` script enables a subset of the Config API: xref:configuration-guide:config-api.adoc#commands-for-common-properties[(un)setting common properties] and xref:configuration-guide:config-api.adoc#commands-for-user-defined-properties[(un)setting user-defined properties].
 +
 +`bin/solr config [options]`
 +
 +`bin/solr config -help`
 +
 +=== Set or Unset Common Properties
 +
 +To set the common property `updateHandler.autoCommit.maxDocs` to `100` on collection `mycollection`:
 +
 +`bin/solr config -c mycollection -p 8983 -action set-property -property updateHandler.autoCommit.maxDocs -value 100`
 +
 +The default `-action` is `set-property`, so the above can be shortened by not mentioning it:
 +
 +`bin/solr config -c mycollection -p 8983 -property updateHandler.autoCommit.maxDocs -value 100`
 +
 +To unset a previously set common property, specify `-action unset-property` with no `-value`:
 +
 +`bin/solr config -c mycollection -p 8983 -action unset-property -property updateHandler.autoCommit.maxDocs`
 +
 +=== Set or Unset User-Defined Properties
 +
 +To set the user-defined property `update.autoCreateFields` to `false` (to disable xref:indexing-guide:schemaless-mode.adoc[]):
 +
 +`bin/solr config -c mycollection -p 8983 -action set-user-property -property update.autoCreateFields -value false`
 +
 +To unset a previously set user-defined property, specify `-action unset-user-property` with no `-value`:
 +
 +`bin/solr config -c mycollection -p 8983 -action unset-user-property -property update.autoCreateFields`
 +
 +=== Config Parameters
 +
 +`-c <name>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +Name of the core or collection on which to change configuration.
 +
 +`-action <name>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `set-property`
 +|===
 ++
 +Config API action, one of: `set-property`, `unset-property`, `set-user-property`, `unset-user-property`.
 +
 +`-property <name>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +Name of the property to change.
 +
 +`-value <new-value>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +Set the property to this value.
 +
 +`-z <zkHost>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +The ZooKeeper connection string, usable in SolrCloud mode.
 +Unnecessary if `ZK_HOST` is defined in `solr.in.sh` or `solr.in.cmd`.
 +
 +`-p <port>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +`localhost` port of the Solr node to use when applying the configuration change.
 +
 +`-solrUrl <url>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +Base Solr URL, which can be used in SolrCloud mode to determine the ZooKeeper connection string if that's not known.
 +
 +== ZooKeeper Operations
 +
 +The `bin/solr` script allows certain operations affecting ZooKeeper.
 +These operations are for SolrCloud mode only.
 +
 +The operations are available as sub-commands, which each have their own set of options.
 +
 +`bin/solr zk [sub-command] [options]`
 +
 +`bin/solr zk -help`
 +
 +NOTE: Solr should have been started at least once before issuing these commands to initialize ZooKeeper with the znodes Solr expects.
 +Once ZooKeeper is initialized, Solr doesn't need to be running on any node to use these commands.
 +
 +=== Upload a Configuration Set
 +
 +Use the `zk upconfig` command to upload one of the pre-configured configuration set or a customized configuration set to ZooKeeper.
 +
 +==== ZK Upload Parameters
 +
 +All parameters below are required.
 +
 +`-n <name>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +Name of the configuration set in ZooKeeper.
 +This command will upload the configuration set to the "configs" ZooKeeper node giving it the name specified.
 ++
 +You can see all uploaded configuration sets in the Admin UI via the Cloud screens.
 +Choose Cloud -> Tree -> configs to see them.
 ++
 +If a pre-existing configuration set is specified, it will be overwritten in ZooKeeper.
 ++
 +*Example*: `-n myconfig`
 +
 +`-d <configset dir>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The path of the configuration set to upload.
 +It should have a `conf` directory immediately below it that in turn contains `solrconfig.xml` etc.
 ++
 +If just a name is supplied, `$SOLR_HOME/server/solr/configsets` will be checked for this name.
 +An absolute path may be supplied instead.
 ++
 +*Examples*:
 +
 +* `-d directory_under_configsets`
 +* `-d /path/to/configset/source`
 +
 +`-z <zkHost>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The ZooKeeper connection string.
 +Is not required if `ZK_HOST` is defined in `solr.in.sh` or `solr.in.cmd`.
 ++
 +*Example*: `-z 123.321.23.43:2181`
 +
 +An example of this command with all of the parameters is:
 +
 +[source,bash]
 +bin/solr zk upconfig -z 111.222.333.444:2181 -n mynewconfig -d /path/to/configset
 +
 +.Reload Collections When Changing Configurations
 +[WARNING]
 +====
 +This command does *not* automatically make changes effective!
 +It simply uploads the configuration sets to ZooKeeper.
 +You can use the Collection API's xref:collection-management.adoc#reload[RELOAD command] to reload any collections that uses this configuration set.
 +====
 +
 +=== Download a Configuration Set
 +
 +Use the `zk downconfig` command to download a configuration set from ZooKeeper to the local filesystem.
 +
 +==== ZK Download Parameters
 +
 +All parameters listed below are required.
 +
 +`-n <name>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +Name of the configset in ZooKeeper to download.
 +The Admin UI Cloud -> Tree -> configs node lists all available configuration sets.
 ++
 +*Example*: `-n myconfig`
 +
 +`-d <configset dir>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The path to write the downloaded configuration set into.
 +If just a name is supplied, `$SOLR_HOME/server/solr/configsets` will be the parent.
 +An absolute path may be supplied as well.
 ++
 +In either case, _pre-existing configurations at the destination will be overwritten_!
 ++
 +*Examples*:
 +
 +* `-d directory_under_configsets`
 +* `-d /path/to/configset/destination`
 +
 +`-z <zkHost>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The ZooKeeper connection string.
 +Unnecessary if `ZK_HOST` is defined in `solr.in.sh` or `solr.in.cmd`.
 ++
 +*Example*: `-z 123.321.23.43:2181`
 +
 +An example of this command with all parameters is:
 +
 +[source,bash]
 +bin/solr zk downconfig -z 111.222.333.444:2181 -n mynewconfig -d /path/to/configset
 +
 +A best practice is to keep your configuration sets in some form of version control as the system-of-record.
 +In that scenario, `downconfig` should rarely be used.
 +
 +=== Copy between Local Files and ZooKeeper znodes
 +
 +Use the `zk cp` command for transferring files and directories between ZooKeeper znodes and your local drive.
 +This command will copy from the local drive to ZooKeeper, from ZooKeeper to the local drive or from ZooKeeper to ZooKeeper.
 +
 +==== ZK Copy Parameters
 +
 +`-r`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +Do a recursive copy.
 +The command will fail if the `<src>` has children unless `-r` is specified.
 ++
 +*Example*: `-r`
 +
 +`<src>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The file or path to copy from.
 +If prefixed with `zk:` then the source is presumed to be ZooKeeper.
 +If no prefix or the prefix is `file`: this is the local drive.
 +At least one of `<src>` or `<dest>` must be prefixed by `'zk:'` or the command will fail.
 ++
 +*Examples*:
 +
 +* `zk:/configs/myconfigs/solrconfig.xml`
 +* `file:/Users/apache/configs/src`
 +
 +`<dest>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The file or path to copy to.
 +If prefixed with `zk:` then the source is presumed to be ZooKeeper.
 +If no prefix or the prefix is `file:` this is the local drive.
 ++
 +At least one of `<src>` or `<dest>` must be prefixed by `zk:` or the command will fail.
 +If `<dest>` ends in a slash character it names a directory.
 ++
 +*Examples*:
 +
 +* `zk:/configs/myconfigs/solrconfig.xml`
 +* `file:/Users/apache/configs/src`
 +
 +`-z <zkHost>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The ZooKeeper connection string.
 +Optional if `ZK_HOST` is defined in `solr.in.sh` or `solr.in.cmd`.
 ++
 +*Example*: `-z 123.321.23.43:2181`
 +
 +An example of this command with the parameters is:
 +
 +Recursively copy a directory from local to ZooKeeper.
 +
 +`bin/solr zk cp -r file:/apache/confgs/whatever/conf zk:/configs/myconf -z 111.222.333.444:2181`
 +
 +Copy a single file from ZooKeeper to local.
 +
 +`bin/solr zk cp zk:/configs/myconf/managed_schema /configs/myconf/managed_schema -z 111.222.333.444:2181`
 +
 +=== Remove a znode from ZooKeeper
 +
 +Use the `zk rm` command to remove a znode (and optionally all child nodes) from ZooKeeper.
 +
 +==== ZK Remove Parameters
 +
 +`-r`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +Do a recursive removal.
 +The command will fail if the `<path>` has children unless `-r` is specified.
 ++
 +*Example*: `-r`
 +
 +`<path>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The path to remove from ZooKeeper, either a parent or leaf node.
 ++
 +There are limited safety checks, you cannot remove `/` or `/zookeeper` nodes.
 ++
 +The path is assumed to be a ZooKeeper node, no `zk:` prefix is necessary.
 ++
 +*Examples*:
 +
 +* `/configs`
 +* `/configs/myconfigset`
 +* `/configs/myconfigset/solrconfig.xml`
 +
 +`-z <zkHost>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The ZooKeeper connection string.
 +Optional if `ZK_HOST` is defined in `solr.in.sh` or `solr.in.cmd`.
 ++
 +*Example*: `-z 123.321.23.43:2181`
 +
 +Examples of this command with the parameters are:
 +
 +`bin/solr zk rm -r /configs`
 +
 +`bin/solr zk rm /configs/myconfigset/schema.xml`
 +
 +
 +=== Move One ZooKeeper znode to Another (Rename)
 +
 +Use the `zk mv` command to move (rename) a ZooKeeper znode.
 +
 +==== ZK Move Parameters
 +
 +`<src>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The znode to rename.
 +The `zk:` prefix is assumed.
 ++
 +*Example*: `/configs/oldconfigset`
 +
 +`<dest>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The new name of the znode.
 +The `zk:` prefix is assumed.
 ++
 +*Example*: `/configs/newconfigset`
 +
 +`-z <zkHost>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The ZooKeeper connection string.
 +Unnecessary if `ZK_HOST` is defined in `solr.in.sh` or `solr.in.cmd`.
 ++
 +*Example*: `-z 123.321.23.43:2181`
 +
 +An example of this command is:
 +
 +`bin/solr zk mv /configs/oldconfigset /configs/newconfigset`
 +
 +
 +=== List a ZooKeeper znode's Children
 +
 +Use the `zk ls` command to see the children of a znode.
 +
 +==== ZK List Parameters
 +
 +`-r`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +Recursively list all descendants of a znode.
 ++
 +*Example*: `-r`
 +
 +`<path>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The path on ZooKeeper to list.
 ++
 +*Example*: `/collections/mycollection`
 +
 +`-z <zkHost>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The ZooKeeper connection string.
 +Optional if `ZK_HOST` is defined in `solr.in.sh` or `solr.in.cmd`.
 ++
 +*Example*: `-z 123.321.23.43:2181`
 +
 +An example of this command with the parameters is:
 +
 +`bin/solr zk ls -r /collections/mycollection`
 +
 +`bin/solr zk ls /collections`
 +
 +
 +=== Create a znode (supports chroot)
 +
 +Use the `zk mkroot` command to create a znode.
 +The primary use-case for this command to support ZooKeeper's "chroot" concept.
 +However, it can also be used to create arbitrary paths.
 +
 +==== Create znode Parameters
 +
 +`<path>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The path on ZooKeeper to create.
 +Intermediate znodes will be created if necessary.
 +A leading slash is assumed even if not specified.
 ++
 +*Example*: `/solr`
 +
 +`-z <zkHost>`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The ZooKeeper connection string.
 +Optional if `ZK_HOST` is defined in `solr.in.sh` or `solr.in.cmd`.
 ++
 +*Example*: `-z 123.321.23.43:2181`
 +
 +Examples of this command:
 +
 +`bin/solr zk mkroot /solr -z 123.321.23.43:2181`
 +
 +`bin/solr zk mkroot /solr/production`
 +
 +== Exporting Documents to a File
 +
 +The `export` command will allow you to export documents from a collection in either JSON or Javabin format.
 +All documents can be exported, or only those that match a query.
 +
 +`bin/solr export [options]`
 +
 +`bin/solr export -help`
 +
 +The `bin/solr export` command takes the following parameters:
 +
 +`url`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +Fully-qualified address to a collection.
 ++
 +*Example*: `-url http://localhost:8983/solr/techproducts`
 +
 +`format`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `jsonl`
 +|===
 ++
 +The file format of the export, `jsonl` or `javabin`.
 +Choosing `javabin` exports to a file with extension `.javabin` which is the native Solr format.
 +This is compact and faster to import.
 +
 +`-out`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: _see description_
 +|===
 ++
 +The file name of the export.
 +If the file name ends with `json.gz` the output will be compressed into a .gz file.
 ++
 +If not provided, a file will be created with the name of the collection, as in `<collection>.json`.
 +
 +`query`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `\*:*`
 +|===
 ++
 +A custom query.
 +The default is `\*:*` which will export all documents.
 +
 +`fields`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +A comma separated list of fields to be exported.
 +If not provided, all fields will be included.
 +
 +`limit`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `100`
 +|===
 ++
 +The number of documents to export.
 +The value `-1` will export all documents.
 +
 +*Examples*
 +
 +Export all documents from a collection `gettingstarted`:
 +
 +[source,bash]
 +bin/solr export -url http://localhost:8983/solr/gettingstarted limit -1
 +
 +Export all documents of collection `gettingstarted` into a file called `1MDocs.json.gz` as a zipped JSON file:
 +
 +[source,bash]
 +----
 +bin/solr export -url http://localhost:8983/solr/gettingstarted -1 -out 1MDocs.json.gz
 +----
 +
 +=== Importing Documents to a Collection
 +
 +Once you have exported documents in a file, you can use the xref:indexing-guide:indexing-with-update-handlers.adoc[/update request handler] to import them to a new Solr collection.
 +
 +*Example: import `jsonl` files*
 +
 +`curl -X POST -d @gettingstarted.json http://localhost:8983/solr/gettingstarted/update/json/docs?commit=true`
 +
 +*Example: import `javabin` files*
 +
 +`curl -X POST --header "Content-Type: application/javabin" --data-binary @gettingstarted.javabin http://localhost:8983/solr/gettingstarted/update?commit=true`
diff --cc solr/solr-ref-guide/modules/indexing-guide/pages/filters.adoc
index 9fd4b73,0000000..087df83
mode 100644,000000..100644
--- a/solr/solr-ref-guide/modules/indexing-guide/pages/filters.adoc
+++ b/solr/solr-ref-guide/modules/indexing-guide/pages/filters.adoc
@@@ -1,3761 -1,0 +1,3761 @@@
 += Filters
 +// Licensed to the Apache Software Foundation (ASF) under one
 +// or more contributor license agreements.  See the NOTICE file
 +// distributed with this work for additional information
 +// regarding copyright ownership.  The ASF licenses this file
 +// to you under the Apache License, Version 2.0 (the
 +// "License"); you may not use this file except in compliance
 +// with the License.  You may obtain a copy of the License at
 +//
 +//   http://www.apache.org/licenses/LICENSE-2.0
 +//
 +// Unless required by applicable law or agreed to in writing,
 +// software distributed under the License is distributed on an
 +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 +// KIND, either express or implied.  See the License for the
 +// specific language governing permissions and limitations
 +// under the License.
 +
 +Filters examine a stream of tokens and keep them, transform them, or discard them depending on the filter type being used.
 +
 +== About Filters
 +
 +Like xref:tokenizers.adoc[tokenizers], filters consume input and produce a stream of tokens.
 +Filters also derive from `org.apache.lucene.analysis.TokenStream` but unlike tokenizers, a filter's input is another TokenStream.
 +The job of a filter is usually easier than that of a tokenizer since in most cases a filter looks at each token in the stream sequentially and decides whether to pass it along, replace it, or discard it.
 +
 +A filter may also do more complex analysis by looking ahead to consider multiple tokens at once, although this is less common.
 +One hypothetical use for such a filter might be to normalize state names that would be tokenized as two words.
 +For example, the single token "california" would be replaced with "CA", while the token pair "rhode" followed by "island" would become the single token "RI".
 +
 +Because filters consume one `TokenStream` and produce a new `TokenStream`, they can be chained one after another indefinitely.
 +Each filter in the chain in turn processes the tokens produced by its predecessor.
 +The order in which you specify the filters is therefore significant.
 +Typically, the most general filtering is done first, and later filtering stages are more specialized.
 +
 +=== Filter Configuration
 +Filters are configured with a `<filter>` element in the schema file as a child of `<analyzer>`, following the `<tokenizer>` element.
 +
 +For example:
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filterexample]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<fieldType name="text" class="solr.TextField">
 +  <analyzer>
 +    <tokenizer name="standard"/>
 +    <filter name="lowercase"/>
 +    <filter name="englishPorter"/>
 +  </analyzer>
 +</fieldType>
 +----
 +====
 +[example.tab-pane#byclass-filterexample]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<fieldType name="text" class="solr.TextField">
 +  <analyzer>
 +    <tokenizer class="solr.StandardTokenizerFactory"/>
 +    <filter class="solr.LowerCaseFilterFactory"/>
 +    <filter class="solr.EnglishPorterFilterFactory"/>
 +  </analyzer>
 +</fieldType>
 +----
 +====
 +--
 +
 +This example starts with Solr's standard tokenizer, which breaks the field's text into tokens.
 +All the tokens are then set to lowercase, which will facilitate case-insensitive matching at query time.
 +
 +The last filter in the above example is a stemmer filter that uses the Porter stemming algorithm.
 +
 +=== Stemming
 +A stemmer is basically a set of mapping rules that maps the various forms of a word back to the base, or _stem_, word from which they derive.
 +
 +For example, in English the words "hugs", "hugging" and "hugged" are all forms of the stem word "hug".
 +The stemmer will replace all of these terms with "hug", which is what will be indexed.
 +This means that a query for "hug" will match the term "hugged", but not "huge".
 +
 +Conversely, applying a stemmer to your query terms will allow queries containing non-stemmed terms, like "hugging", to match documents with different variations of the same stem word, such as "hugged".
 +This works because both the indexer and the query will map to the same stem ("hug").
 +
 +Word stemming is, obviously, very language specific.
 +Solr includes several language-specific stemmers created by the http://snowball.tartarus.org/[Snowball] generator that are based on the Porter stemming algorithm.
 +The generic <<Snowball Porter Stemmer Filter>> can be used to configure any of these language stemmers.
 +Solr also includes a convenience wrapper for the English Snowball stemmer.
 +There are also several purpose-built stemmers for non-English languages.
 +These stemmers are described in xref:language-analysis.adoc[].
 +
 +=== Filters with Arguments
 +
 +Arguments may be passed to tokenizer factories to modify their behavior by setting attributes on the `<filter>` element.
 +For example:
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter2]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<fieldType name="semicolonDelimited" class="solr.TextField">
 +  <analyzer type="query">
 +    <tokenizer name="pattern" pattern="; " />
 +    <filter name="length" min="2" max="7"/>
 +  </analyzer>
 +</fieldType>
 +----
 +====
 +[example.tab-pane#byclass-filter-2]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<fieldType name="semicolonDelimited" class="solr.TextField">
 +  <analyzer type="query">
 +    <tokenizer class="solr.PatternTokenizerFactory" pattern="; " />
 +    <filter class="solr.LengthFilterFactory" min="2" max="7"/>
 +  </analyzer>
 +</fieldType>
 +----
 +====
 +--
 +
 +The following sections describe the filter factories that are included in this release of Solr.
 +
 +== ASCII Folding Filter
 +
 +This filter converts alphabetic, numeric, and symbolic Unicode characters which are not in the Basic Latin Unicode block (the first 127 ASCII characters) to their ASCII equivalents, if one exists.
 +This filter converts characters from the following Unicode blocks:
 +
 +* http://www.unicode.org/charts/PDF/U0080.pdf[C1 Controls and Latin-1 Supplement] (PDF)
 +* http://www.unicode.org/charts/PDF/U0100.pdf[Latin Extended-A] (PDF)
 +* http://www.unicode.org/charts/PDF/U0180.pdf[Latin Extended-B] (PDF)
 +* http://www.unicode.org/charts/PDF/U1E00.pdf[Latin Extended Additional] (PDF)
 +* http://www.unicode.org/charts/PDF/U2C60.pdf[Latin Extended-C] (PDF)
 +* http://www.unicode.org/charts/PDF/UA720.pdf[Latin Extended-D] (PDF)
 +* http://www.unicode.org/charts/PDF/U0250.pdf[IPA Extensions] (PDF)
 +* http://www.unicode.org/charts/PDF/U1D00.pdf[Phonetic Extensions] (PDF)
 +* http://www.unicode.org/charts/PDF/U1D80.pdf[Phonetic Extensions Supplement] (PDF)
 +* http://www.unicode.org/charts/PDF/U2000.pdf[General Punctuation] (PDF)
 +* http://www.unicode.org/charts/PDF/U2070.pdf[Superscripts and Subscripts] (PDF)
 +* http://www.unicode.org/charts/PDF/U2460.pdf[Enclosed Alphanumerics] (PDF)
 +* http://www.unicode.org/charts/PDF/U2700.pdf[Dingbats] (PDF)
 +* http://www.unicode.org/charts/PDF/U2E00.pdf[Supplemental Punctuation] (PDF)
 +* http://www.unicode.org/charts/PDF/UFB00.pdf[Alphabetic Presentation Forms] (PDF)
 +* http://www.unicode.org/charts/PDF/UFF00.pdf[Halfwidth and Fullwidth Forms] (PDF)
 +
 +*Factory class:* `solr.ASCIIFoldingFilterFactory`
 +
 +*Arguments:*
 +
 +`preserveOriginal`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `false`
 +|===
 ++
 +If `true`, the original token is preserved: "thé" -> "the", "thé"
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-asciifolding]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="whitespace"/>
 +  <filter name="asciiFolding" preserveOriginal="false" />
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-asciifolding]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.WhitespaceTokenizer"/>
 +  <filter class="solr.ASCIIFoldingFilterFactory" preserveOriginal="false" />
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "á" (Unicode character 00E1)
 +
 +*Out:* "a" (ASCII character 97)
 +
 +== Beider-Morse Filter
 +
 +Implements the Beider-Morse Phonetic Matching (BMPM) algorithm, which allows identification of similar names, even if they are spelled differently or in different languages.
 +More information about how this works is available in the section xref:phonetic-matching.adoc#beider-morse-phonetic-matching-bmpm[Beider-Morse Phonetic Matching].
 +
 +[IMPORTANT]
 +====
 +BeiderMorseFilter changed its behavior in Solr 5.0 due to an update to version 3.04 of the BMPM algorithm.
 +Older version of Solr implemented BMPM version 3.00 (see http://stevemorse.org/phoneticinfo.htm).
 +Any index built using this filter with earlier versions of Solr will need to be rebuilt.
 +====
 +
 +*Factory class:* `solr.BeiderMorseFilterFactory`
 +
 +*Arguments:*
 +
 +`nameType`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `GENERIC`
 +|===
 ++
 +Types of names.
 +Valid values are `GENERIC`, `ASHKENAZI`, or `SEPHARDIC`.
 +If not processing Ashkenazi or Sephardic names, use `GENERIC`.
 +
 +`ruleType`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `APPROX`
 +|===
 ++
 +Types of rules to apply.
 +Valid values are `APPROX` or `EXACT`.
 +
 +`concat`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `true`
 +|===
 ++
 +Defines if multiple possible matches should be combined with a pipe (`|`).
 +
 +`languageSet`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `auto`
 +|===
 ++
 +The language set to use.
 +The value `auto` will allow the filter to identify the language, or a comma-separated list can be supplied.
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-beidermorse]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="beiderMorse" nameType="GENERIC" ruleType="APPROX" concat="true" languageSet="auto">
 +  </filter>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-beidermorse]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.BeiderMorseFilterFactory" nameType="GENERIC" ruleType="APPROX" concat="true" languageSet="auto">
 +  </filter>
 +</analyzer>
 +----
 +====
 +--
 +
 +== Classic Filter
 +
 +This filter takes the output of the xref:tokenizers.adoc#classic-tokenizer[Classic Tokenizer] and strips periods from acronyms and "'s" from possessives.
 +
 +*Factory class:* `solr.ClassicFilterFactory`
 +
 +*Arguments:* None
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-classic]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="classic"/>
 +  <filter name="classic"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-classic]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.ClassicTokenizerFactory"/>
 +  <filter class="solr.ClassicFilterFactory"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "I.B.M. cat's can't"
 +
 +*Tokenizer to Filter:* "I.B.M", "cat's", "can't"
 +
 +*Out:* "IBM", "cat", "can't"
 +
 +== Common Grams Filter
 +
 +This filter for use in `index` time analysis creates word shingles by combining common tokens such as stop words with regular tokens.
 +This can result in an index with more unique terms, but is useful for creating phrase queries containing common words, such as "the cat", in a way that will typically be much faster then if the combined tokens are not used, because only the term positions of documents containg both terms in sequence have to be considered.
 +Correct usage requires being paired with <<Common Grams Query Filter>> during `query` analysis.
 +
 +These filters can also be combined with <<Stop Filter>> so searching for `"the cat"` would match different documents then `"a cat"`, while pathological searches for either `"the"` or `"a"` would not match any documents.
 +
 +*Factory class:* `solr.CommonGramsFilterFactory`
 +
 +*Arguments:*
 +
 +`words`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The name of a common word file in .txt format, such as `stopwords.txt`.
 +
 +`format`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +If the stopwords list has been formatted for Snowball, you can specify `format="snowball"` so Solr can read the stopwords file.
 +
 +`ignoreCase`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `false`
 +|===
 ++
 +If `true`, the filter ignores the case of words when comparing them to the common word file.
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-commongrams]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer name="whitespace"/>
 +  <filter name="commonGrams" words="stopwords.txt" ignoreCase="true"/>
 +</analyzer>
 +<analyzer type="query">
 +  <tokenizer name="whitespace"/>
 +  <filter name="commonGramsQuery" words="stopwords.txt" ignoreCase="true"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-commongrams]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer class="solr.WhitespaceTokenizerFactory"/>
 +  <filter class="solr.CommonGramsFilterFactory" words="stopwords.txt" ignoreCase="true"/>
 +</analyzer>
 +<analyzer type="query">
 +  <tokenizer class="solr.WhitespaceTokenizerFactory"/>
 +  <filter class="solr.CommonGramsQueryFilterFactory" words="stopwords.txt" ignoreCase="true"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "the cat in the hat"
 +
 +*Tokenizer to Filter(s):* "the", "cat", "in", "the", "hat"
 +
 +*(Index) Out:* "the"(1), "the_cat"(1), "cat"(2), "cat_in"(2), "in"(3), "in_the"(3), "the"(4), "the_hat"(4), "hat"(5)
 +
 +*(Query) Out:* "the_cat"(1), "cat_in"(2), "in_the"(3), "the_hat"(4)
 +
 +== Common Grams Query Filter
 +
 +This filter is used for the `query` time analysis aspect of <<Common Grams Filter>> -- see that filer for a description of arguments, example configuration, and sample input/output.
 +
 +== Collation Key Filter
 +
 +Collation allows sorting of text in a language-sensitive way.
 +It is usually used for sorting, but can also be used with advanced searches.
 +We've covered this in much more detail in the section on xref:language-analysis.adoc#unicode-collation[Unicode Collation].
 +
 +== Daitch-Mokotoff Soundex Filter
 +
 +Implements the Daitch-Mokotoff Soundex algorithm, which allows identification of similar names, even if they are spelled differently.
 +More information about how this works is available in the section on xref:phonetic-matching.adoc[].
 +
 +*Factory class:* `solr.DaitchMokotoffSoundexFilterFactory`
 +
 +*Arguments:*
 +
 +`inject`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `true`
 +|===
 ++
 +If `true`, then new phonetic tokens are added to the stream.
 +Otherwise, tokens are replaced with the phonetic equivalent.
 +Setting this to `false` will enable phonetic matching, but the exact spelling of the target word may not match.
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-daitchmokotoffsondex]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="daitchMokotoffSoundex" inject="true"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-daitchmokotoffsondex]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.DaitchMokotoffSoundexFilterFactory" inject="true"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +== Double Metaphone Filter
 +
 +This filter creates tokens using the http://commons.apache.org/proper/commons-codec/archives/{ivy-commons-codec-version}/apidocs/org/apache/commons/codec/language/DoubleMetaphone.html[`DoubleMetaphone`] encoding algorithm from commons-codec.
 +For more information, see xref:phonetic-matching.adoc[].
 +
 +*Factory class:* `solr.DoubleMetaphoneFilterFactory`
 +
 +*Arguments:*
 +
 +`inject`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `true`
 +|===
 ++
 +If `true`, then new phonetic tokens are added to the stream.
 +Otherwise, tokens are replaced with the phonetic equivalent.
 +Setting this to `false` will enable phonetic matching, but the exact spelling of the target word may not match.
 +
 +`maxCodeLength`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +The maximum length of the code to be generated.
 +
 +*Example:*
 +
 +Default behavior for inject (`true`): keep the original token and add phonetic token(s) at the same position.
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-doublemetaphone]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="doubleMetaphone"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-doublemetaphone]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.DoubleMetaphoneFilterFactory"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "four score and Kuczewski"
 +
 +*Tokenizer to Filter:* "four"(1), "score"(2), "and"(3), "Kuczewski"(4)
 +
 +*Out:* "four"(1), "FR"(1), "score"(2), "SKR"(2), "and"(3), "ANT"(3), "Kuczewski"(4), "KSSK"(4), "KXFS"(4)
 +
 +The phonetic tokens have a position increment of 0, which indicates that they are at the same position as the token they were derived from (immediately preceding).
 +Note that "Kuczewski" has two encodings, which are added at the same position.
 +
 +*Example:*
 +
 +Discard original token (`inject="false"`).
 +
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="doubleMetaphone" inject="false"/>
 +</analyzer>
 +----
 +
 +*In:* "four score and Kuczewski"
 +
 +*Tokenizer to Filter:* "four"(1), "score"(2), "and"(3), "Kuczewski"(4)
 +
 +*Out:* "FR"(1), "SKR"(2), "ANT"(3), "KSSK"(4), "KXFS"(4)
 +
 +Note that "Kuczewski" has two encodings, which are added at the same position.
 +
 +== Delimited Boost Filter
 +
 +This filter adds a numeric floating point boost value to tokens, splitting on a delimiter character.
 +
 +*Factory class:* `solr.DelimitedBoostTokenFilterFactory`
 +
 +*Arguments:*
 +
 +`delimiter`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `\|` (_pipe symbol_)
 +|===
 ++
 +The character used to separate the token and the boost.
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-delimitedBoost]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +<tokenizer name="standard"/>
 +<filter name="delimitedBoost"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-delimitedBoost]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +<tokenizer class="solr.StandardTokenizerFactory"/>
 +<filter class="solr.DelimitedBoostTokenFilterFactory"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "leopard|0.5 panthera uncia|0.9"
 +
 +*Tokenizer to Filter:* "leopard|0.5"(1), "panthera"(2), "uncia|0.9"(3)
 +
 +*Out:* "leopard"(1)[0.5], "panthera"(2), "uncia"(3)[0.9]
 +
 +The numeric floating point in square brackets is a float token boost attribute.
 +
 +*Example:*
 +
 +Using a different delimiter (`delimiter="/"`).
 +
 +[source,xml]
 +----
 +<analyzer>
 +<tokenizer name="standard"/>
 +<filter name="delimitedBoost" delimiter="/"/>
 +</analyzer>
 +----
 +
 +*In:* "leopard/0.5 panthera uncia/0.9"
 +
 +*Tokenizer to Filter:* "leopard/0.5"(1), "panthera"(2), "uncia/0.9"(3)
 +
 +*Out:* "leopard"(1)[0.5], "panthera"(2), "uncia"(3)[0.9]
 +
 +*N.B.* make sure the delimiter is compatible with the tokenizer you use
 +
 +== Edge N-Gram Filter
 +
 +This filter generates edge n-gram tokens of sizes within the given range.
 +
 +*Factory class:* `solr.EdgeNGramFilterFactory`
 +
 +*Arguments:*
 +
 +`minGramSize`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `1`
 +|===
 +The minimum gram size.
 +
 +`maxGramSize`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `1`
 +|===
 +The maximum gram size.
 +
 +`preserveOriginal`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `false`
 +|===
 ++
 +If `true` keep the original term even if it is shorter than `minGramSize` or longer than `maxGramSize`.
 +
 +*Example:*
 +
 +Default behavior.
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-edgengram]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="edgeNGram"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-edgengram]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.EdgeNGramFilterFactory"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "four score and twenty"
 +
 +*Tokenizer to Filter:* "four", "score", "and", "twenty"
 +
 +*Out:* "f", "s", "a", "t"
 +
 +*Example:*
 +
 +A range of 1 to 4.
 +
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="edgeNGram" minGramSize="1" maxGramSize="4"/>
 +</analyzer>
 +----
 +
 +*In:* "four score"
 +
 +*Tokenizer to Filter:* "four", "score"
 +
 +*Out:* "f", "fo", "fou", "four", "s", "sc", "sco", "scor"
 +
 +*Example:*
 +
 +A range of 4 to 6.
 +
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="edgeNGram" minGramSize="4" maxGramSize="6"/>
 +</analyzer>
 +----
 +
 +*In:* "four score and twenty"
 +
 +*Tokenizer to Filter:* "four", "score", "and", "twenty"
 +
 +*Out:* "four", "scor", "score", "twen", "twent", "twenty"
 +
 +*Example:*
 +
 +Preserve original term.
 +
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="edgeNGram" minGramSize="2" maxGramSize="3" preserveOriginal="true"/>
 +</analyzer>
 +----
 +
 +*In:* "four score"
 +
 +*Tokenizer to Filter:* "four", "score"
 +
 +*Out:* "fo", "fou", "four", "sc, "sco", "score"
 +
 +== English Minimal Stem Filter
 +
 +This filter stems plural English words to their singular form.
 +
 +*Factory class:* `solr.EnglishMinimalStemFilterFactory`
 +
 +*Arguments:* None
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-englishminimalstem]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer name="standard"/>
 +  <filter name="englishMinimalStem"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-englishminimalstem]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.EnglishMinimalStemFilterFactory"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "dogs cats"
 +
 +*Tokenizer to Filter:* "dogs", "cats"
 +
 +*Out:* "dog", "cat"
 +
 +== English Possessive Filter
 +
 +This filter removes singular possessives (trailing *'s*) from words.
 +Note that plural possessives, e.g., the *s'* in "divers' snorkels", are not removed by this filter.
 +
 +*Factory class:* `solr.EnglishPossessiveFilterFactory`
 +
 +*Arguments:* None
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-englishpossessive]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="whitespace"/>
 +  <filter name="englishPossessive"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-englishpossessive]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.WhitespaceTokenizerFactory"/>
 +  <filter class="solr.EnglishPossessiveFilterFactory"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "Man's dog bites dogs' man"
 +
 +*Tokenizer to Filter:* "Man's", "dog", "bites", "dogs'", "man"
 +
 +*Out:* "Man", "dog", "bites", "dogs'", "man"
 +
 +== Fingerprint Filter
 +
 +This filter outputs a single token which is a concatenation of the sorted and de-duplicated set of input tokens.
 +This can be useful for clustering/linking use cases.
 +
 +*Factory class:* `solr.FingerprintFilterFactory`
 +
 +*Arguments:*
 +
 +`separator`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: _space character_
 +|===
 ++
 +The character used to separate tokens combined into the single output token.
 +
 +`maxOutputTokenSize`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `1024`
 +|===
 ++
 +The maximum length of the summarized output token.
 +If exceeded, no output token is emitted.
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-fingerprint]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer name="whitespace"/>
 +  <filter name="fingerprint" separator="_" />
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-fingerprint]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer class="solr.WhitespaceTokenizerFactory"/>
 +  <filter class="solr.FingerprintFilterFactory" separator="_" />
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "the quick brown fox jumped over the lazy dog"
 +
 +*Tokenizer to Filter:* "the", "quick", "brown", "fox", "jumped", "over", "the", "lazy", "dog"
 +
 +*Out:* "brown_dog_fox_jumped_lazy_over_quick_the"
 +
 +== Flatten Graph Filter
 +
 +This filter must be included on index-time analyzer specifications that include at least one graph-aware filter, including Synonym Graph Filter and Word Delimiter Graph Filter.
 +
 +*Factory class:* `solr.FlattenGraphFilterFactory`
 +
 +*Arguments:* None
 +
 +See the examples below for <<Synonym Graph Filter>> and <<Word Delimiter Graph Filter>>.
 +
 +== Hunspell Stem Filter
 +
 +The `Hunspell Stem Filter` provides support for several languages.
 +You must provide the dictionary (`.dic`) and rules (`.aff`) files for each language you wish to use with the Hunspell Stem Filter.
 +You can download those language files http://wiki.services.openoffice.org/wiki/Dictionaries[here].
 +
 +Be aware that your results will vary widely based on the quality of the provided dictionary and rules files.
 +For example, some languages have only a minimal word list with no morphological information.
 +On the other hand, for languages that have no stemmer but do have an extensive dictionary file, the Hunspell stemmer may be a good choice.
 +
 +*Factory class:* `solr.HunspellStemFilterFactory`
 +
 +*Arguments:*
 +
 +`dictionary`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The path to a dictionary file.
 +
 +`affix`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The path of a rules file.
 +
 +`ignoreCase`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `false`
 +|===
 ++
 +Controls whether matching is case sensitive or not.
 +
 +`strictAffixParsing`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `true`
 +|===
 ++
 +Controls whether the affix parsing is strict or not.
 +If `true`, an error while reading an affix rule causes a ParseException, otherwise is ignored.
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-hunspellstem]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer name="whitespace"/>
 +  <filter name="hunspellStem"
 +    dictionary="en_GB.dic"
 +    affix="en_GB.aff"
 +    ignoreCase="true"
 +    strictAffixParsing="true" />
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-hunspellstem]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer class="solr.WhitespaceTokenizerFactory"/>
 +  <filter class="solr.HunspellStemFilterFactory"
 +    dictionary="en_GB.dic"
 +    affix="en_GB.aff"
 +    ignoreCase="true"
 +    strictAffixParsing="true" />
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "jump jumping jumped"
 +
 +*Tokenizer to Filter:* "jump", "jumping", "jumped"
 +
 +*Out:* "jump", "jump", "jump"
 +
 +== Hyphenated Words Filter
 +
 +This filter reconstructs hyphenated words that have been tokenized as two tokens because of a line break or other intervening whitespace in the field test.
 +If a token ends with a hyphen, it is joined with the following token and the hyphen is discarded.
 +
 +Note that for this filter to work properly, the upstream tokenizer must not remove trailing hyphen characters.
 +This filter is generally only useful at index time.
 +
 +*Factory class:* `solr.HyphenatedWordsFilterFactory`
 +
 +*Arguments:* None
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-hyphenatedwords]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer name="whitespace"/>
 +  <filter name="hyphenatedWords"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-hyphenatedwords]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer class="solr.WhitespaceTokenizerFactory"/>
 +  <filter class="solr.HyphenatedWordsFilterFactory"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "A hyphen- ated word"
 +
 +*Tokenizer to Filter:* "A", "hyphen-", "ated", "word"
 +
 +*Out:* "A", "hyphenated", "word"
 +
 +== ICU Folding Filter
 +
 +This filter is a custom Unicode normalization form that applies the foldings specified in http://www.unicode.org/reports/tr30/tr30-4.html[Unicode TR #30: Character Foldings] in addition to the `NFKC_Casefold` normalization form as described in <<ICU Normalizer 2 Filter>>.
 +This filter is a better substitute for the combined behavior of the <<ASCII Folding Filter>>, <<Lower Case Filter>>, and <<ICU Normalizer 2 Filter>>.
 +
 +To use this filter, you must add additional .jars to Solr's classpath (as described in the section xref:configuration-guide:solr-plugins.adoc#installing-plugins[Installing Plugins]).
 +See `solr/contrib/analysis-extras/README.md` for instructions on which jars you need to add.
 +
 +*Factory class:* `solr.ICUFoldingFilterFactory`
 +
 +*Arguments:*
 +
 +`filter`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 +A Unicode set filter that can be used to e.g., exclude a set of characters from being processed.
 +See the http://icu-project.org/apiref/icu4j/com/ibm/icu/text/UnicodeSet.html[UnicodeSet javadocs] for more information.
 +
 +*Example without a filter:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-icufolding]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="icuFolding"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-icufolding]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.ICUFoldingFilterFactory"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*Example with a filter to exclude Swedish/Finnish characters:*
 +
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="icuFolding" filter="[^åäöÅÄÖ]"/>
 +</analyzer>
 +----
 +
 +For detailed information on this normalization form, see http://www.unicode.org/reports/tr30/tr30-4.html[Unicode TR #30: Character Foldings].
 +
 +== ICU Normalizer 2 Filter
 +
 +This filter factory normalizes text according to one of five Unicode Normalization Forms as described in http://unicode.org/reports/tr15/[Unicode Standard Annex #15]:
 +
 +* NFC: (`name="nfc" mode="compose"`) Normalization Form C, canonical decomposition
 +* NFD: (`name="nfc" mode="decompose"`) Normalization Form D, canonical decomposition, followed by canonical composition
 +* NFKC: (`name="nfkc" mode="compose"`) Normalization Form KC, compatibility decomposition
 +* NFKD: (`name="nfkc" mode="decompose"`) Normalization Form KD, compatibility decomposition, followed by canonical composition
 +* NFKC_Casefold: (`name="nfkc_cf" mode="compose"`) Normalization Form KC, with additional Unicode case folding.
 +Using the ICU Normalizer 2 Filter is a better-performing substitution for the <<Lower Case Filter>> and NFKC normalization.
 +
 +*Factory class:* `solr.ICUNormalizer2FilterFactory`
 +
 +*Arguments:*
 +
 +`form`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: `nfkc_cf`
 +|===
 ++
 +The name of the normalization form.
 +Valid options are `nfc`, `nfd`, `nfkc`, `nfkd`, or `nfkc_cf`.
 +
 +`mode`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: `compose`
 +|===
 ++
 +The mode of Unicode character composition and decomposition.
 +Valid options are: `compose` or `decompose`.
 +
 +`filter`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +A Unicode set filter that can be used to e.g., exclude a set of characters from being processed.
 +See the http://icu-project.org/apiref/icu4j/com/ibm/icu/text/UnicodeSet.html[UnicodeSet javadocs] for more information.
 +
 +*Example with NFKC_Casefold:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-icunormalizer2]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="icuNormalizer2" form="nfkc_cf" mode="compose"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-icunormalizer2]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.ICUNormalizer2FilterFactory" form="nfkc_cf" mode="compose"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*Example with a filter to exclude Swedish/Finnish characters:*
 +
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="icuNormalizer2" form="nfkc_cf" mode="compose" filter="[^åäöÅÄÖ]"/>
 +</analyzer>
 +----
 +
 +For detailed information about these normalization forms, see http://unicode.org/reports/tr15/[Unicode Normalization Forms].
 +
 +To use this filter, you must add additional .jars to Solr's classpath (as described in the section xref:configuration-guide:solr-plugins.adoc#installing-plugins[Installing Plugins]).
 +See `solr/contrib/analysis-extras/README.md` for instructions on which jars you need to add.
 +
 +== ICU Transform Filter
 +
 +This filter applies http://userguide.icu-project.org/transforms/general[ICU Tranforms] to text.
 +This filter supports only ICU System Transforms.
 +Custom rule sets are not supported.
 +
 +*Factory class:* `solr.ICUTransformFilterFactory`
 +
 +*Arguments:*
 +
 +`id`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The identifier for the ICU System Transform you wish to apply with this filter.
 +For a full list of ICU System Transforms, see http://demo.icu-project.org/icu-bin/translit?TEMPLATE_FILE=data/translit_rule_main.html.
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-icutransform]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="icuTransform" id="Traditional-Simplified"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-icutransform]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.ICUTransformFilterFactory" id="Traditional-Simplified"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +For detailed information about ICU Transforms, see http://userguide.icu-project.org/transforms/general.
 +
 +To use this filter, you must add additional .jars to Solr's classpath (as described in the section xref:configuration-guide:solr-plugins.adoc#installing-plugins[Installing Plugins]).
 +See `solr/contrib/analysis-extras/README.md` for instructions on which jars you need to add.
 +
 +== Keep Word Filter
 +
 +This filter discards all tokens except those that are listed in the given word list.
 +This is the inverse of the Stop Words Filter.
 +This filter can be useful for building specialized indices for a constrained set of terms.
 +
 +*Factory class:* `solr.KeepWordFilterFactory`
 +
 +*Arguments:*
 +
 +`words`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +Path to a text file containing the list of keep words, one per line.
 +Blank lines and lines that begin with `\#` are ignored.
 +This may be an absolute path, or a simple filename in the Solr `conf` directory.
 +
 +`ignoreCase`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `false`
 +|===
 ++
 +If `true` then comparisons are done case-insensitively.
 +If this argument is true, then the words file is assumed to contain only lowercase words.
 +
 +*Example:*
 +
 +Where `keepwords.txt` contains:
 +
 +`happy funny silly`
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-keepword]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="keepWord" words="keepwords.txt"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-keepword]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.KeepWordFilterFactory" words="keepwords.txt"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "Happy, sad or funny"
 +
 +*Tokenizer to Filter:* "Happy", "sad", "or", "funny"
 +
 +*Out:* "funny"
 +
 +*Example:*
 +
 +Same `keepwords.txt`, case insensitive:
 +
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="keepWord" words="keepwords.txt" ignoreCase="true"/>
 +</analyzer>
 +----
 +
 +*In:* "Happy, sad or funny"
 +
 +*Tokenizer to Filter:* "Happy", "sad", "or", "funny"
 +
 +*Out:* "Happy", "funny"
 +
 +*Example:*
 +
 +Using LowerCaseFilterFactory before filtering for keep words, no `ignoreCase` flag.
 +
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="lowercase"/>
 +  <filter name="keepWord" words="keepwords.txt"/>
 +</analyzer>
 +----
 +
 +*In:* "Happy, sad or funny"
 +
 +*Tokenizer to Filter:* "Happy", "sad", "or", "funny"
 +
 +*Filter to Filter:* "happy", "sad", "or", "funny"
 +
 +*Out:* "happy", "funny"
 +
 +== KStem Filter
 +
 +KStem is an alternative to the Porter Stem Filter for developers looking for a less aggressive stemmer.
 +KStem was written by Bob Krovetz, ported to Lucene by Sergio Guzman-Lara (UMASS Amherst).
 +This stemmer is only appropriate for English language text.
 +
 +*Factory class:* `solr.KStemFilterFactory`
 +
 +*Arguments:* None
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-kstem]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer name="standard"/>
 +  <filter name="kStem"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-kstem]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.KStemFilterFactory"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "jump jumping jumped"
 +
 +*Tokenizer to Filter:* "jump", "jumping", "jumped"
 +
 +*Out:* "jump", "jump", "jump"
 +
 +== Length Filter
 +
 +This filter passes tokens whose length falls within the min/max limit specified.
 +All other tokens are discarded.
 +
 +*Factory class:* `solr.LengthFilterFactory`
 +
 +*Arguments:*
 +
 +`min`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 +Minimum token length.
 +Tokens shorter than this are discarded.
 +
 +`max`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +Maximum token length.
 +Must be larger than `min`.
 +Tokens longer than this are discarded.
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-length]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="length" min="3" max="7"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-length]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.LengthFilterFactory" min="3" max="7"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "turn right at Albuquerque"
 +
 +*Tokenizer to Filter:* "turn", "right", "at", "Albuquerque"
 +
 +*Out:* "turn", "right"
 +
 +== Limit Token Count Filter
 +
 +This filter limits the number of accepted tokens, typically useful for index analysis.
 +
 +By default, this filter ignores any tokens in the wrapped `TokenStream` once the limit has been reached, which can result in `reset()` being called prior to `incrementToken()` returning `false`.
 +For most `TokenStream` implementations this should be acceptable, and faster then consuming the full stream.
 +If you are wrapping a `TokenStream` which requires that the full stream of tokens be exhausted in order to function properly, use the `consumeAllTokens="true"` option.
 +
 +*Factory class:* `solr.LimitTokenCountFilterFactory`
 +
 +*Arguments:*
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +Maximum token count.
 +After this limit has been reached, tokens are discarded.
 +
 +`consumeAllTokens`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `false`
 +|===
 ++
 +Whether to consume (and discard) previous token filters' tokens after the maximum token count has been reached.
 +See description above.
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-limittokencount]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer name="whitespace"/>
 +  <filter name="limitTokenCount" maxTokenCount="10"
 +          consumeAllTokens="false" />
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-limittokencount]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer class="solr.WhitespaceTokenizerFactory"/>
 +  <filter class="solr.LimitTokenCountFilterFactory" maxTokenCount="10"
 +          consumeAllTokens="false" />
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "1 2 3 4 5 6 7 8 9 10 11 12"
 +
 +*Tokenizer to Filter:* "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"
 +
 +*Out:* "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"
 +
 +== Limit Token Offset Filter
 +
 +This filter limits tokens to those before a configured maximum start character offset.
 +This can be useful to limit highlighting, for example.
 +
 +By default, this filter ignores any tokens in the wrapped `TokenStream` once the limit has been reached, which can result in `reset()` being called prior to `incrementToken()` returning `false`.
 +For most `TokenStream` implementations this should be acceptable, and faster then consuming the full stream.
 +If you are wrapping a `TokenStream` which requires that the full stream of tokens be exhausted in order to function properly, use the `consumeAllTokens="true"` option.
 +
 +*Factory class:* `solr.LimitTokenOffsetFilterFactory`
 +
 +*Arguments:*
 +
 +`maxStartOffset`:: (integer, required) Maximum token start character offset.
 +After this limit has been reached, tokens are discarded.
 +
 +`consumeAllTokens`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `false`
 +|===
 ++
 +Whether to consume (and discard) previous token filters' tokens after the maximum start offset has been reached.
 +See description above.
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-limittokenoffset]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="whitespace"/>
 +  <filter name="limitTokenOffset" maxStartOffset="10"
 +          consumeAllTokens="false" />
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-limittokenoffset]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.WhitespaceTokenizerFactory"/>
 +  <filter class="solr.LimitTokenOffsetFilterFactory" maxStartOffset="10"
 +          consumeAllTokens="false" />
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "0 2 4 6 8 A C E"
 +
 +*Tokenizer to Filter:* "0", "2", "4", "6", "8", "A", "C", "E"
 +
 +*Out:* "0", "2", "4", "6", "8", "A"
 +
 +== Limit Token Position Filter
 +
 +This filter limits tokens to those before a configured maximum token position.
 +
 +By default, this filter ignores any tokens in the wrapped `TokenStream` once the limit has been reached, which can result in `reset()` being called prior to `incrementToken()` returning `false`.
 +For most `TokenStream` implementations this should be acceptable, and faster then consuming the full stream.
 +If you are wrapping a `TokenStream` which requires that the full stream of tokens be exhausted in order to function properly, use the `consumeAllTokens="true"` option.
 +
 +*Factory class:* `solr.LimitTokenPositionFilterFactory`
 +
 +*Arguments:*
 +
 +`maxTokenPosition`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +Maximum token position.
 +After this limit has been reached, tokens are discarded.
 +
 +`consumeAllTokens`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `false`
 +|===
 ++
 +Whether to consume (and discard) previous token filters' tokens after the maximum start offset has been reached.
 +See description above.
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-limittokenposition]
 +====
 +[.tab-label]*With name)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="whitespace"/>
 +  <filter name="limitTokenPosition" maxTokenPosition="3"
 +          consumeAllTokens="false" />
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-limittokenposition]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.WhitespaceTokenizerFactory"/>
 +  <filter class="solr.LimitTokenPositionFilterFactory" maxTokenPosition="3"
 +          consumeAllTokens="false" />
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "1 2 3 4 5"
 +
 +*Tokenizer to Filter:* "1", "2", "3", "4", "5"
 +
 +*Out:* "1", "2", "3"
 +
 +== Lower Case Filter
 +
 +Converts any uppercase letters in a token to the equivalent lowercase token.
 +All other characters are left unchanged.
 +
 +*Factory class:* `solr.LowerCaseFilterFactory`
 +
 +*Arguments:* None
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-lowercase]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="lowercase"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-lowercase]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.LowerCaseFilterFactory"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "Down With CamelCase"
 +
 +*Tokenizer to Filter:* "Down", "With", "CamelCase"
 +
 +*Out:* "down", "with", "camelcase"
 +
 +== Managed Stop Filter
 +
 +This is specialized version of the <<Stop Filter,Stop Words Filter Factory>> that uses a set of stop words that are xref:configuration-guide:managed-resources.adoc[managed from a REST API].
 +
 +*Arguments:*
 +
 +`managed`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The name that should be used for this set of stop words in the managed REST API.
 +
 +*Example:*
 +//TODO: make this show an actual API call.
 +With this configuration the set of words is named "english" and can be managed via `/solr/collection_name/schema/analysis/stopwords/english`
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-managedstop]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="managedStop" managed="english"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-managedstop]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.ManagedStopFilterFactory" managed="english"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +See <<Stop Filter>> for example input/output.
 +
 +== Managed Synonym Filter
 +
 +This is specialized version of the <<Synonym Filter>> that uses a mapping on synonyms that is xref:configuration-guide:managed-resources.adoc[managed from a REST API].
 +
 +.Managed Synonym Filter has been Deprecated
 +[WARNING]
 +====
 +Managed Synonym Filter has been deprecated in favor of Managed Synonym Graph Filter, which is required for multi-term synonym support.
 +====
 +
 +*Factory class:* `solr.ManagedSynonymFilterFactory`
 +
 +For arguments and examples, see the <<Synonym Graph Filter>> below.
 +
 +== Managed Synonym Graph Filter
 +
 +This is specialized version of the <<Synonym Graph Filter>> that uses a mapping on synonyms that is xref:configuration-guide:managed-resources.adoc[managed from a REST API].
 +
 +This filter maps single- or multi-token synonyms, producing a fully correct graph output.
 +This filter is a replacement for the Managed Synonym Filter, which produces incorrect graphs for multi-token synonyms.
 +
 +NOTE: Although this filter produces correct token graphs, it cannot consume an input token graph correctly.
 +
 +*Arguments:*
 +
 +`managed`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The name that should be used for this mapping on synonyms in the managed REST API.
 +
 +*Example:*
 +//TODO: make this show an actual API call
 +With this configuration the set of mappings is named "english" and can be managed via `/solr/collection_name/schema/analysis/synonyms/english`
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-managedsynonymgraph]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer name="standard"/>
 +  <filter name="managedSynonymGraph" managed="english"/>
 +  <filter name="flattenGraph"/> <!-- required on index analyzers after graph filters -->
 +</analyzer>
 +<analyzer type="query">
 +  <tokenizer name="standard"/>
 +  <filter name="managedSynonymGraph" managed="english"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-managedsynonymgraph]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.ManagedSynonymGraphFilterFactory" managed="english"/>
 +  <filter class="solr.FlattenGraphFilterFactory"/> <!-- required on index analyzers after graph filters -->
 +</analyzer>
 +<analyzer type="query">
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.ManagedSynonymGraphFilterFactory" managed="english"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +See <<Synonym Graph Filter>> below for example input/output.
 +
 +== MinHash Filter
 +
 +Generates a repeatably random fixed number of hash tokens from all the input tokens in the stream.
 +To do this it first consumes all of the input tokens from its source.
 +This filter would normally be preceded by a <<Shingle Filter>>, as shown in the example below.
 +
 +Each input token is hashed.
 +It is subsequently "rehashed" `hashCount` times by combining with a set of precomputed hashes.
 +For each of the resulting hashes, the hash space is divided in to `bucketCount` buckets.
 +The lowest set of `hashSetSize` hashes (usually a set of one) is generated for each bucket.
 +
 +This filter generates one type of signature or sketch for the input tokens and can be used to compute Jaccard similarity between documents.
 +
 +*Arguments:*
 +
 +`hashCount`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `1`
 +|===
 ++
 +The number of hashes to use.
 +
 +`bucketCount`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `512`
 +|===
 ++
 +The number of buckets to use.
 +
 +`hashSetSize`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `1`
 +|===
 ++
 +The size of the set for the lowest hashes from each bucket.
 +
 +`withRotation`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: _see description_
 +|===
 ++
 +If a hash bucket is empty, generate a hash value from the first previous bucket that has a value.
 +The default is `true` if the `bucketCount` is greater than `1` and `false` otherwise.
 +
 +The number of hashes generated depends on the options above.
 +With the default settings for `withRotation`, the number of hashes generated is `hashCount` x `bucketCount` x `hashSetSize` => 512, by default.
 +
 +*Example:*
 +
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.ICUTokenizerFactory"/>
 +  <filter class="solr.ICUFoldingFilterFactory"/>
 +  <filter class="solr.ShingleFilterFactory" minShingleSize="5" outputUnigrams="false" outputUnigramsIfNoShingles="false" maxShingleSize="5" tokenSeparator=" "/>
 +  <filter class="org.apache.lucene.analysis.minhash.MinHashFilterFactory" bucketCount="512" hashSetSize="1" hashCount="1"/>
 +</analyzer>
 +----
 +
 +*In:* "woof woof woof woof woof"
 +
 +*Tokenizer to Filter:* "woof woof woof woof woof"
 +
 +*Out:* "℁팽徭聙↝ꇁ홱杯", "℁팽徭聙↝ꇁ홱杯", "℁팽徭聙↝ꇁ홱杯",     .... a total of 512 times
 +
 +== N-Gram Filter
 +
 +Generates n-gram tokens of sizes in the given range.
 +Note that tokens are ordered by position and then by gram size.
 +
 +*Factory class:* `solr.NGramFilterFactory`
 +
 +*Arguments:*
 +
 +`minGramSize`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `1`
 +|===
 +The minimum gram size.
 +
 +`maxGramSize`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `2`
 +|===
 ++
 +The maximum gram size.
 +
 +`preserveOriginal`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `false`
 +|===
 ++
 +If `true` keep the original term even if it is shorter than `minGramSize` or longer than `maxGramSize`.
 +
 +*Example:*
 +
 +Default behavior.
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-ngram]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="nGram"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-ngram]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.NGramFilterFactory"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "four score"
 +
 +*Tokenizer to Filter:* "four", "score"
 +
 +*Out:* "f", "o", "u", "r", "fo", "ou", "ur", "s", "c", "o", "r", "e", "sc", "co", "or", "re"
 +
 +*Example:*
 +
 +A range of 1 to 4.
 +
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="nGram" minGramSize="1" maxGramSize="4"/>
 +</analyzer>
 +----
 +
 +*In:* "four score"
 +
 +*Tokenizer to Filter:* "four", "score"
 +
 +*Out:* "f", "fo", "fou", "four", "o", "ou", "our", "u", "ur", "r", "s", "sc", "sco", "scor", "c", "co", "cor", "core", "o", "or", "ore", "r", "re", "e"
 +
 +*Example:*
 +
 +A range of 3 to 5.
 +
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="nGram" minGramSize="3" maxGramSize="5"/>
 +</analyzer>
 +----
 +
 +*In:* "four score"
 +
 +*Tokenizer to Filter:* "four", "score"
 +
 +*Out:* "fou", "four", "our", "sco", "scor", "score", "cor", "core", "ore"
 +
 +*Example:*
 +
 +Preserve original term.
 +
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="nGram" minGramSize="2" maxGramSize="3" preserveOriginal="true"/>
 +</analyzer>
 +----
 +
 +*In:* "four score"
 +
 +*Tokenizer to Filter:* "four", "score"
 +
 +*Out:* "fo", "fou", "ou", "our", "ur", "four", "sc", "sco", "co", "cor", "or", "ore", "re", "score"
 +
 +== Numeric Payload Token Filter
 +
 +This filter adds a numeric floating point payload value to tokens that match a given type.
 +Refer to the Javadoc for the `org.apache.lucene.analysis.Token` class for more information about token types and payloads.
 +
 +*Factory class:* `solr.NumericPayloadTokenFilterFactory`
 +
 +*Arguments:*
 +
 +`payload`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +A floating point value that will be added to all matching tokens.
 +
 +`typeMatch`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +A token type name string.
 +Tokens with a matching type name will have their payload set to the above floating point value.
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-numericpayload]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="whitespace"/>
 +  <filter name="numericPayload" payload="0.75" typeMatch="word"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-numericpayload]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.WhitespaceTokenizerFactory"/>
 +  <filter class="solr.NumericPayloadTokenFilterFactory" payload="0.75" typeMatch="word"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "bing bang boom"
 +
 +*Tokenizer to Filter:* "bing", "bang", "boom"
 +
 +*Out:* "bing"[0.75], "bang"[0.75], "boom"[0.75]
 +
 +== Pattern Replace Filter
 +
 +This filter applies a regular expression to each token and, for those that match, substitutes the given replacement string in place of the matched pattern.
 +Tokens which do not match are passed though unchanged.
 +
 +*Factory class:* `solr.PatternReplaceFilterFactory`
 +
 +*Arguments:*
 +
 +`pattern`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The regular expression to test against each token, as per `java.util.regex.Pattern`.
 +
 +`replacement`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +A string to substitute in place of the matched pattern.
 +This string may contain references to capture groups in the regex pattern.
 +See the Javadoc for `java.util.regex.Matcher`.
 +
 +`replace`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `all`
 +|===
 ++
 +Indicates whether all occurrences of the pattern (`all`) in the token should be replaced, or only the first (`first`).
 +
 +*Example:*
 +
 +Simple string replace:
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-patternreplace]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="patternReplace" pattern="cat" replacement="dog"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-patternreplace]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.PatternReplaceFilterFactory" pattern="cat" replacement="dog"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "cat concatenate catycat"
 +
 +*Tokenizer to Filter:* "cat", "concatenate", "catycat"
 +
 +*Out:* "dog", "condogenate", "dogydog"
 +
 +*Example:*
 +
 +String replacement, first occurrence only:
 +
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="patternReplace" pattern="cat" replacement="dog" replace="first"/>
 +</analyzer>
 +----
 +
 +*In:* "cat concatenate catycat"
 +
 +*Tokenizer to Filter:* "cat", "concatenate", "catycat"
 +
 +*Out:* "dog", "condogenate", "dogycat"
 +
 +*Example:*
 +
 +More complex pattern with capture group reference in the replacement.
 +Tokens that start with non-numeric characters and end with digits will have an underscore inserted before the numbers.
 +Otherwise the token is passed through.
 +
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="patternReplace" pattern="(\D+)(\d+)$" replacement="$1_$2"/>
 +</analyzer>
 +----
 +
 +*In:* "cat foo1234 9987 blah1234foo"
 +
 +*Tokenizer to Filter:* "cat", "foo1234", "9987", "blah1234foo"
 +
 +*Out:* "cat", "foo_1234", "9987", "blah1234foo"
 +
 +== Phonetic Filter
 +
 +This filter creates tokens using one of the phonetic encoding algorithms in the `org.apache.commons.codec.language` package.
 +For more information, see the section on xref:phonetic-matching.adoc[].
 +
 +*Factory class:* `solr.PhoneticFilterFactory`
 +
 +*Arguments:*
 +
 +`encoder`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The name of the encoder to use.
 +The encoder name must be one of the following (case insensitive):
 +
 +* `http://commons.apache.org/proper/commons-codec/archives/{ivy-commons-codec-version}/apidocs/org/apache/commons/codec/language/DoubleMetaphone.html[DoubleMetaphone]`
 +* `http://commons.apache.org/proper/commons-codec/archives/{ivy-commons-codec-version}/apidocs/org/apache/commons/codec/language/Metaphone.html[Metaphone]`
 +* `http://commons.apache.org/proper/commons-codec/archives/{ivy-commons-codec-version}/apidocs/org/apache/commons/codec/language/Soundex.html[Soundex]`
 +* `http://commons.apache.org/proper/commons-codec/archives/{ivy-commons-codec-version}/apidocs/org/apache/commons/codec/language/RefinedSoundex.html[RefinedSoundex]`
 +* `http://commons.apache.org/proper/commons-codec/archives/{ivy-commons-codec-version}/apidocs/org/apache/commons/codec/language/Caverphone.html[Caverphone]` (v2.0)
 +* `http://commons.apache.org/proper/commons-codec/archives/{ivy-commons-codec-version}/apidocs/org/apache/commons/codec/language/ColognePhonetic.html[ColognePhonetic]`
 +* `http://commons.apache.org/proper/commons-codec/archives/{ivy-commons-codec-version}/apidocs/org/apache/commons/codec/language/Nysiis.html[Nysiis]`
 +
 +`inject`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `true`
 +|===
 ++
 +If `true`, new phonetic tokens are added to the stream.
 +Otherwise, tokens are replaced with the phonetic equivalent.
 +Setting this to `false` will enable phonetic matching, but the exact spelling of the target word may not match.
 +
 +`maxCodeLength`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 +The maximum length of the code to be generated by the Metaphone or Double Metaphone encoders.
 +
 +*Example:*
 +
 +Default behavior for DoubleMetaphone encoding.
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-phonetic]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="phonetic" encoder="DoubleMetaphone"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-phonetic]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.PhoneticFilterFactory" encoder="DoubleMetaphone"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "four score and twenty"
 +
 +*Tokenizer to Filter:* "four"(1), "score"(2), "and"(3), "twenty"(4)
 +
 +*Out:* "four"(1), "FR"(1), "score"(2), "SKR"(2), "and"(3), "ANT"(3), "twenty"(4), "TNT"(4)
 +
 +The phonetic tokens have a position increment of 0, which indicates that they are at the same position as the token they were derived from (immediately preceding).
 +
 +*Example:*
 +
 +Discard original token.
 +
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="phonetic" encoder="DoubleMetaphone" inject="false"/>
 +</analyzer>
 +----
 +
 +*In:* "four score and twenty"
 +
 +*Tokenizer to Filter:* "four"(1), "score"(2), "and"(3), "twenty"(4)
 +
 +*Out:* "FR"(1), "SKR"(2), "ANT"(3), "TWNT"(4)
 +
 +*Example:*
 +
 +Default Soundex encoder.
 +
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="phonetic" encoder="Soundex"/>
 +</analyzer>
 +----
 +
 +*In:* "four score and twenty"
 +
 +*Tokenizer to Filter:* "four"(1), "score"(2), "and"(3), "twenty"(4)
 +
 +*Out:* "four"(1), "F600"(1), "score"(2), "S600"(2), "and"(3), "A530"(3), "twenty"(4), "T530"(4)
 +
 +== Porter Stem Filter
 +
 +This filter applies the Porter Stemming Algorithm for English.
 +The results are similar to using the Snowball Porter Stemmer with the `language="English"` argument.
 +But this stemmer is coded directly in Java and is not based on Snowball.
 +It does not accept a list of protected words and is only appropriate for English language text.
 +However, it has been benchmarked as http://markmail.org/thread/d2c443z63z37rwf6[four times faster] than the English Snowball stemmer, so can provide a performance enhancement.
 +
 +*Factory class:* `solr.PorterStemFilterFactory`
 +
 +*Arguments:* None
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-porterstem]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer name="standard"/>
 +  <filter name="porterStem"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-porterstem]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer class="solr.StandardTokenizerFactory "/>
 +  <filter class="solr.PorterStemFilterFactory"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "jump jumping jumped"
 +
 +*Tokenizer to Filter:* "jump", "jumping", "jumped"
 +
 +*Out:* "jump", "jump", "jump"
 +
 +== Protected Term Filter
 +
 +This filter enables a form of conditional filtering: it only applies its wrapped filters to terms that are *not contained* in a protected set.
 +
 +*Factory class:* `solr.ProtectedTermFilterFactory`
 +
 +*Arguments:*
 +
 +`protected`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +Comma-separated list of files containing protected terms, one per line.
 +
 +`wrappedFilters`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +Case-insensitive comma-separated list of `TokenFilterFactory` SPI names (strip trailing `(Token)FilterFactory` from the factory name - see the https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html[`java.util.ServiceLoader interface`]).
 +Each filter name must be unique, so if you need to specify the same filter more than once, you must add case-insensitive unique `-id` suffixes to each same-SPI-named filter (note that the `-id` suffix is stripped prior to SPI lookup).
 +
 +`ignoreCase`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `false`
 +|===
 ++
 +Ignore case when testing for protected words.
 +If `true`, the protected list should contain lowercase words.
 +
 +*Example:*
 +
 +All terms except those in `protectedTerms.txt` are truncated at 4 characters and lowercased:
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-protectedterm]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="whitespace"/>
 +  <filter name="protectedTerm"
 +          ignoreCase="true" protected="protectedTerms.txt"
 +          wrappedFilters="truncate,lowercase"
 +          truncate.prefixLength="4"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-protectedterm]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.WhitespaceTokenizerFactory"/>
 +  <filter class="solr.ProtectedTermFilterFactory"
 +          ignoreCase="true" protected="protectedTerms.txt"
 +          wrappedFilters="truncate,lowercase"
 +          truncate.prefixLength="4"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*Example:*
 +
 +This example includes multiple same-named wrapped filters with unique `-id` suffixes.
 +Note that both the filter SPI names and `-id` suffixes are treated case-insensitively.
 +
 +For all terms except those in `protectedTerms.txt`, synonyms are added, terms are reversed, and then synonyms are added for the reversed terms:
 +
 +[source,xml]
 +----
 +<analyzer type="query">
 +  <tokenizer name="whitespace"/>
 +  <filter name="protectedTerm"
 +          ignoreCase="true" protected="protectedTerms.txt"
 +          wrappedFilters="SynonymGraph-fwd,ReverseString,SynonymGraph-rev"
 +          synonymgraph-FWD.synonyms="fwd-syns.txt"
 +          synonymgraph-FWD.synonyms="rev-syns.txt"/>
 +</analyzer>
 +----
 +
 +== Remove Duplicates Token Filter
 +
 +The filter removes duplicate tokens in the stream.
 +Tokens are considered to be duplicates ONLY if they have the same text and position values.
 +
 +Because positions must be the same, this filter might not do what a user expects it to do based on its name.
 +It is a very specialized filter that is only useful in very specific circumstances.
 +It has been so named for brevity, even though it is potentially misleading.
 +
 +*Factory class:* `solr.RemoveDuplicatesTokenFilterFactory`
 +
 +*Arguments:* None
 +
 +*Example:*
 +
 +One example of where `RemoveDuplicatesTokenFilterFactory` is useful in situations where a synonym file is being used in conjunction with a stemmer.
 +In these situations, both the stemmer and the synonym filter can cause completely identical terms with the same positions to end up in the stream, increasing index size with no benefit.
 +
 +Consider the following entry from a `synonyms.txt` file:
 +
 +[source,text]
 +----
 + Television, Televisions, TV, TVs
 +----
 +
 +When used in the following configuration:
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-removeduplicates]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer type="query">
 +  <tokenizer name="standard"/>
 +  <filter name="synonymGraph" synonyms="synonyms.txt"/>
 +  <filter name="englishMinimalStem"/>
 +  <filter name="removeDuplicates"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-removeduplicates]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer type="query">
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.SynonymGraphFilterFactory" synonyms="synonyms.txt"/>
 +  <filter class="solr.EnglishMinimalStemFilterFactory"/>
 +  <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "Watch TV"
 +
 +*Tokenizer to Synonym Filter:* "Watch"(1) "TV"(2)
 +
 +*Synonym Filter to Stem Filter:* "Watch"(1) "Television"(2) "Televisions"(2) "TV"(2) "TVs"(2)
 +
 +*Stem Filter to Remove Dups Filter:* "Watch"(1) "Television"(2) "Television"(2) "TV"(2) "TV"(2)
 +
 +*Out:* "Watch"(1) "Television"(2) "TV"(2)
 +
 +== Reversed Wildcard Filter
 +
 +This filter reverses tokens to provide faster leading wildcard and prefix queries.
 +Tokens without wildcards are not reversed.
 +
 +*Factory class:* `solr.ReversedWildcardFilterFactory`
 +
 +*Arguments:*
 +
 +`withOriginal`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `true`
 +|===
 +If `true`, the filter produces both original and reversed tokens at the same positions.
 +If `false`, produces only reversed tokens.
 +
 +`maxPosAsterisk`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `2`
 +|===
 ++
 +The maximum position of the asterisk wildcard ('*') that triggers the reversal of the query term.
 +Terms with asterisks at positions above this value are not reversed.
 +
 +`maxPosQuestion`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `1`
 +|===
 ++
 +The maximum position of the question mark wildcard ('?') that triggers the reversal of query term.
 +To reverse only pure suffix queries (queries with a single leading asterisk), set this to 0 and `maxPosAsterisk` to 1.
 +
 +`maxFractionAsterisk`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `0.0`
 +|===
 ++
 +An additional parameter that triggers the reversal if asterisk ('*') position is less than this fraction of the query token length.
 +
 +`minTrailing`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `2`
 +|===
 ++
 +The minimum number of trailing characters in a query token after the last wildcard character.
 +For good performance this should be set to a value larger than `1`.
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-reversedwildcard]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer name="whitespace"/>
 +  <filter name="reversedWildcard" withOriginal="true"
 +    maxPosAsterisk="2" maxPosQuestion="1" minTrailing="2" maxFractionAsterisk="0"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-reversedwildcard]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer class="solr.WhitespaceTokenizerFactory"/>
 +  <filter class="solr.ReversedWildcardFilterFactory" withOriginal="true"
 +    maxPosAsterisk="2" maxPosQuestion="1" minTrailing="2" maxFractionAsterisk="0"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "*foo *bar"
 +
 +*Tokenizer to Filter:* "*foo", "*bar"
 +
 +*Out:* "oof*", "rab*"
 +
 +== Shingle Filter
 +
 +This filter constructs shingles, which are token n-grams, from the token stream.
 +It combines runs of tokens into a single token.
 +
 +*Factory class:* `solr.ShingleFilterFactory`
 +
 +*Arguments:*
 +
 +`minShingleSize`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `2`
 +|===
 ++
 +The minimum number of tokens per shingle.
 +Must be higher than or equal to `2`.
 +
 +`maxShingleSize`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `2`
 +|===
 ++
 +The maximum number of tokens per shingle.
 +Must be higher than or equal to `minShingleSize`.
 +
 +`outputUnigrams`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `true`
 +|===
 ++
 +If `true`, then each individual token is also included at its original position.
 +
 +`outputUnigramsIfNoShingles`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `false`
 +|===
 ++
 +If `true`, then individual tokens will be output if no shingles are possible.
 +
 +`tokenSeparator`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: _space character_
 +|===
 ++
 +The string to use when joining adjacent tokens to form a shingle.
 +
 +`fillerToken`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `_` (underscore)
 +|===
 ++
 +The character used to fill in for removed stop words in order to preserve position increments.
 +
 +*Example:*
 +
 +Default behavior.
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-shingle]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="shingle"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-shingle]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.ShingleFilterFactory"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "To be, or what?"
 +
 +*Tokenizer to Filter:* "To"(1), "be"(2), "or"(3), "what"(4)
 +
 +*Out:* "To"(1), "To be"(1), "be"(2), "be or"(2), "or"(3), "or what"(3), "what"(4)
 +
 +*Example:*
 +
 +A shingle size of four, do not include original token.
 +
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="shingle" maxShingleSize="4" outputUnigrams="false"/>
 +</analyzer>
 +----
 +
 +*In:* "To be, or not to be."
 +
 +*Tokenizer to Filter:* "To"(1), "be"(2), "or"(3), "not"(4), "to"(5), "be"(6)
 +
 +*Out:* "To be"(1), "To be or"(1), "To be or not"(1), "be or"(2), "be or not"(2), "be or not to"(2), "or not"(3), "or not to"(3), "or not to be"(3), "not to"(4), "not to be"(4), "to be"(5)
 +
 +== Snowball Porter Stemmer Filter
 +
 +This filter factory instantiates a language-specific stemmer generated by Snowball.
 +Snowball is a software package that generates pattern-based word stemmers.
 +This type of stemmer is not as accurate as a table-based stemmer, but is faster and less complex.
 +Table-driven stemmers are labor intensive to create and maintain and so are typically commercial products.
 +
 +Solr contains Snowball stemmers for Armenian, Basque, Catalan, Danish, Dutch, English, Finnish, French, German, Hungarian, Italian, Norwegian, Portuguese, Romanian, Russian, Spanish, Swedish and Turkish.
 +For more information on Snowball, visit http://snowball.tartarus.org/.
 +
 +`StopFilterFactory`, `CommonGramsFilterFactory`, and `CommonGramsQueryFilterFactory` can optionally read stopwords in Snowball format (specify `format="snowball"` in the configuration of those FilterFactories).
 +
 +*Factory class:* `solr.SnowballPorterFilterFactory`
 +
 +*Arguments:*
 +
 +`language`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `English`
 +|===
 ++
 +The name of a language, used to select the appropriate Porter stemmer to use.
 +Case is significant.
 +This string is used to select a package name in the `org.tartarus.snowball.ext` class hierarchy.
 +
 +`protected`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: `protected`
 +|===
 ++
 +Path to a text file containing a list of protected words, one per line.
 +Protected words will not be stemmed.
 +Blank lines and lines that begin with `\#` are ignored.
 +This may be an absolute path, or a simple file name in the Solr `conf` directory.
 +
 +*Example:*
 +
 +Default behavior:
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-snowball]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="snowballPorter"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-snowball]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.SnowballPorterFilterFactory"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "flip flipped flipping"
 +
 +*Tokenizer to Filter:* "flip", "flipped", "flipping"
 +
 +*Out:* "flip", "flip", "flip"
 +
 +*Example:*
 +
 +French stemmer, English words:
 +
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="snowballPorter" language="French"/>
 +</analyzer>
 +----
 +
 +*In:* "flip flipped flipping"
 +
 +*Tokenizer to Filter:* "flip", "flipped", "flipping"
 +
 +*Out:* "flip", "flipped", "flipping"
 +
 +*Example:*
 +
 +Spanish stemmer, Spanish words:
 +
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="snowballPorter" language="Spanish"/>
 +</analyzer>
 +----
 +
 +*In:* "cante canta"
 +
 +*Tokenizer to Filter:* "cante", "canta"
 +
 +*Out:* "cant", "cant"
 +
 +== Stop Filter
 +
 +This filter discards, or _stops_ analysis of, tokens that are on the given stop words list.
 +A standard stop words list is included in the Solr `conf` directory, named `stopwords.txt`, which is appropriate for typical English language text.
 +
 +*Factory class:* `solr.StopFilterFactory`
 +
 +*Arguments:*
 +
 +`words`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +The path to a file that contains a list of stop words, one per line.
 +Blank lines and lines that begin with `\#` are ignored.
 +This may be an absolute path, or path relative to the Solr `conf` directory.
 +
 +`format`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +If the stopwords list has been formatted for Snowball, you can specify `format="snowball"` so Solr can read the stopwords file.
 +
 +`ignoreCase`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `false`
 +|===
 ++
 +Ignore case when testing for stop words.
 +If `true`, the stop list should contain lowercase words.
 +
 +*Example:*
 +
 +Case-sensitive matching, capitalized words not stopped.
 +Token positions skip stopped words.
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-stop]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="stop" words="stopwords.txt"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-stop]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.StopFilterFactory" words="stopwords.txt"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "To be or what?"
 +
 +*Tokenizer to Filter:* "To"(1), "be"(2), "or"(3), "what"(4)
 +
 +*Out:* "To"(1), "what"(4)
 +
 +*Example:*
 +
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="stop" words="stopwords.txt" ignoreCase="true"/>
 +</analyzer>
 +----
 +
 +*In:* "To be or what?"
 +
 +*Tokenizer to Filter:* "To"(1), "be"(2), "or"(3), "what"(4)
 +
 +*Out:* "what"(4)
 +
 +== Suggest Stop Filter
 +
 +Like <<Stop Filter>>, this filter discards, or _stops_ analysis of, tokens that are on the given stop words list.
 +
 +Suggest Stop Filter differs from Stop Filter in that it will not remove the last token unless it is followed by a token separator.
 +For example, a query `"find the"` would preserve the `'the'` since it was not followed by a space, punctuation, etc., and mark it as a `KEYWORD` so that following filters will not change or remove it.
 +
 +By contrast, a query like "`find the popsicle`" would remove '`the`' as a stopword, since it's followed by a space.
 +When using one of the analyzing suggesters, you would normally use the ordinary `StopFilterFactory` in your index analyzer and then SuggestStopFilter in your query analyzer.
 +
 +*Factory class:* `solr.SuggestStopFilterFactory`
 +
 +*Arguments:*
 +
 +`words`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: {lucene-javadocs}/analysis/common/org/apache/lucene/analysis/core/StopAnalyzer.html[`StopAnalyzer#ENGLISH_STOP_WORDS_SET`]
 +|===
 ++
 +The name of a stopwords file to parse.
 +
 +`format`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `wordset`
 +|===
 ++
 +Defines how the words file will be parsed.
 +If `words` is not specified, then `format` must not be specified.
 +The valid values for the `format` parameter are:
 +
 +* `wordset`: Supports one word per line (including any intra-word whitespace) and allows whole line comments beginning with the `\#` character.
 +Blank lines are ignored.
 +* `snowball`: Allows for multiple words specified on each line, and trailing comments may be specified using the vertical line (`|`).
 +Blank lines are ignored.
 +
 +`ignoreCase`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `false`
 +|===
 ++
 +If `true`, matching is case-insensitive.
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-suggeststop]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer type="query">
 +  <tokenizer name="whitespace"/>
 +  <filter name="lowercase"/>
 +  <filter name="suggestStop" ignoreCase="true"
 +          words="stopwords.txt" format="wordset"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-suggeststop]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer type="query">
 +  <tokenizer class="solr.WhitespaceTokenizerFactory"/>
 +  <filter class="solr.LowerCaseFilterFactory"/>
 +  <filter class="solr.SuggestStopFilterFactory" ignoreCase="true"
 +          words="stopwords.txt" format="wordset"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "The The"
 +
 +*Tokenizer to Filter:* "the"(1), "the"(2)
 +
 +*Out:* "the"(2)
 +
 +== Synonym Filter
 +
 +This filter does synonym mapping.
 +Each token is looked up in the list of synonyms and if a match is found, then the synonym is emitted in place of the token.
 +The position value of the new tokens are set such they all occur at the same position as the original token.
 +
 +.Synonym Filter has been Deprecated
 +[WARNING]
 +====
 +Synonym Filter has been deprecated in favor of Synonym Graph Filter, which is required for multi-term synonym support.
 +====
 +
 +*Factory class:* `solr.SynonymFilterFactory`
 +
 +For arguments and examples, see the Synonym Graph Filter below.
 +
 +== Synonym Graph Filter
 +
 +This filter maps single- or multi-token synonyms, producing a fully correct graph output.
 +This filter is a replacement for the Synonym Filter, which produces incorrect graphs for multi-token synonyms.
 +
 +If you use this filter during indexing, you must follow it with a Flatten Graph Filter to squash tokens on top of one another like the Synonym Filter, because the indexer can't directly consume a graph.
 +To get fully correct positional queries when your synonym replacements are multiple tokens, you should instead apply synonyms using this filter at query time.
 +
 +NOTE: Although this filter produces correct token graphs, it cannot consume an input token graph correctly.
 +
 +*Factory class:* `solr.SynonymGraphFilterFactory`
 +
 +*Arguments:*
 +
 +`synonyms`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The path to a file that contains a list of synonyms, one per line.
 +In the (default) `solr` format - see the `format` argument below for alternatives - blank lines and lines that begin with `\#` are ignored.
 +This may be a comma-separated list of paths.
 +See xref:configuration-guide:resource-loading.adoc[] for more information.
 ++
 +There are two ways to specify synonym mappings:
 ++
 +* A comma-separated list of words.
 +If the token matches any of the words, then all the words in the list are substituted, which will include the original token.
 ++
 +* Two comma-separated lists of words with the symbol "\=>" between them.
 +If the token matches any word on the left, then the list on the right is substituted.
 +The original token will not be included unless it is also in the list on the right.
 +
 +`ignoreCase`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `false`
 +|===
 ++
 +If `true`, synonyms will be matched case-insensitively.
 +
 +`expand`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `true`
 +|===
 ++
 +If `true`, a synonym will be expanded to all equivalent synonyms.
 +If `false`, all equivalent synonyms will be reduced to the first in the list.
 +
 +`format`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +(optional; default: `solr`) Controls how the synonyms will be parsed.
 +The short names `solr` (for {lucene-javadocs}/analysis/common/org/apache/lucene/analysis/synonym/SolrSynonymParser.html[`SolrSynonymParser`] and `wordnet` (for {lucene-javadocs}/analysis/common/org/apache/lucene/analysis/synonym/WordnetSynonymParser.html[`WordnetSynonymParser`] ) are supported.
 +You may alternatively supply the name of your own {lucene-javadocs}/analysis/common/org/apache/lucene/analysis/synonym/SynonymMap.Builder.html[`SynonymMap.Builder`] subclass.
 +
 +`tokenizerFactory`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `WhitespaceTokenizerFactory`
 +|===
 ++
 +The name of the tokenizer factory to use when parsing the synonyms file.
 +Arguments with the name prefix `tokenizerFactory.*` will be supplied as init params to the specified tokenizer factory.
 ++
 +Any arguments not consumed by the synonym filter factory, including those without the `tokenizerFactory.*` prefix, will also be supplied as init params to the tokenizer factory.
 ++
 +If `tokenizerFactory` is specified, then `analyzer` may not be, and vice versa.
 +
 +`analyzer`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `WhitespaceTokenizerFactory`
 +|===
 ++
 +The name of the analyzer class to use when parsing the synonyms file.
 +If `analyzer` is specified, then `tokenizerFactory` may not be, and vice versa.
 +
 +For the following examples, assume a synonyms file named `mysynonyms.txt`:
 +
 +[source,text]
 +----
 +couch,sofa,divan
 +teh => the
 +huge,ginormous,humungous => large
 +small => tiny,teeny,weeny
 +----
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-stop-synonymgraph]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer name="standard"/>
 +  <filter name="synonymGraph" synonyms="mysynonyms.txt"/>
 +  <filter name="flattenGraph"/> <!-- required on index analyzers after graph filters -->
 +</analyzer>
 +<analyzer type="query">
 +  <tokenizer name="standard"/>
 +  <filter name="synonymGraph" synonyms="mysynonyms.txt"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-stop-synonymgraph]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.SynonymGraphFilterFactory" synonyms="mysynonyms.txt"/>
 +  <filter class="solr.FlattenGraphFilterFactory"/> <!-- required on index analyzers after graph filters -->
 +</analyzer>
 +<analyzer type="query">
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.SynonymGraphFilterFactory" synonyms="mysynonyms.txt"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "teh small couch"
 +
 +*Tokenizer to Filter:* "teh"(1), "small"(2), "couch"(3)
 +
 +*Out:* "the"(1), "tiny"(2), "teeny"(2), "weeny"(2), "couch"(3), "sofa"(3), "divan"(3)
 +
 +*Example:*
 +
 +*In:* "teh ginormous, humungous sofa"
 +
 +*Tokenizer to Filter:* "teh"(1), "ginormous"(2), "humungous"(3), "sofa"(4)
 +
 +*Out:* "the"(1), "large"(2), "large"(3), "couch"(4), "sofa"(4), "divan"(4)
 +
 +*Weighted Synonyms:*
 +
 +Combining the DelimitedBoostFilter with the Synonym Graph Filter you can achieve Weighted synonyms at query time.
 +For more information feel free to refer to:
 +https://sease.io/2020/03/introducing-weighted-synonyms-in-apache-lucene.html
 +For the following examples, assume a synonyms file named `boostedSynonyms.txt`:
 +
 +[source,text]
 +----
 +leopard, big cat|0.8, bagheera|0.9, panthera pardus|0.85
 +lion => panthera leo|0.9, simba|0.8, kimba|0.75
 +----
 +
 +*Example:*
 +
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer type="query">
 +  <tokenizer name="standard"/>
 +  <filter name="synonymGraph" synonyms="boostedSynonyms.txt"/>
 +  <filter name="delimitedBoost"/>
 +</analyzer>
 +----
 +====
 +
 +*In:* "lion"
 +
 +*Tokenizer to Filter:* "lion"(1)
 +
 +*Out:* "panthera"(1), "leo"(2)[0.9], "simba"(1)[0.8], "kimba"(1)[0.75]
 +
 +== Token Offset Payload Filter
 +
 +This filter adds the numeric character offsets of the token as a payload value for that token.
 +
 +*Factory class:* `solr.TokenOffsetPayloadTokenFilterFactory`
 +
 +*Arguments:* None
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-stop-tokenoffsetpayload]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="whitespace"/>
 +  <filter name="tokenOffsetPayload"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-stop-tokenoffsetpayload]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.WhitespaceTokenizerFactory"/>
 +  <filter class="solr.TokenOffsetPayloadTokenFilterFactory"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "bing bang boom"
 +
 +*Tokenizer to Filter:* "bing", "bang", "boom"
 +
 +*Out:* "bing"[0,4], "bang"[5,9], "boom"[10,14]
 +
 +== Trim Filter
 +
 +This filter trims leading and/or trailing whitespace from tokens.
 +Most tokenizers break tokens at whitespace, so this filter is most often used for special situations.
 +
 +*Factory class:* `solr.TrimFilterFactory`
 +
 +*Arguments:* None
 +
 +*Example:*
 +
 +The PatternTokenizerFactory configuration used here splits the input on simple commas, it does not remove whitespace.
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-trim]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="pattern" pattern=","/>
 +  <filter name="trim"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-trim]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.PatternTokenizerFactory" pattern=","/>
 +  <filter class="solr.TrimFilterFactory"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "one, two , three ,four "
 +
 +*Tokenizer to Filter:* "one", " two ", " three ", "four "
 +
 +*Out:* "one", "two", "three", "four"
 +
 +== Type As Payload Filter
 +
 +This filter adds the token's type, as an encoded byte sequence, as its payload.
 +
 +*Factory class:* `solr.TypeAsPayloadTokenFilterFactory`
 +
 +*Arguments:* None
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-typeaspayload]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="whitespace"/>
 +  <filter name="typeAsPayload"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-typeaspayload]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.WhitespaceTokenizerFactory"/>
 +  <filter class="solr.TypeAsPayloadTokenFilterFactory"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "Pay Bob's I.O.U."
 +
 +*Tokenizer to Filter:* "Pay", "Bob's", "I.O.U."
 +
 +*Out:* "Pay"[<ALPHANUM>], "Bob's"[<APOSTROPHE>], "I.O.U."[<ACRONYM>]
 +
 +== Type As Synonym Filter
 +
 +This filter adds the token's type, as a token at the same position as the token, optionally with a configurable prefix prepended.
 +
 +*Factory class:* `solr.TypeAsSynonymFilterFactory`
 +
 +*Arguments:*
 +
 +`prefix`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +The prefix to prepend to the token's type.
 +
 +*Examples:*
 +
 +With the example below, each token's type will be emitted verbatim at the same position:
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-typeassynonym]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="standard"/>
 +  <filter name="typeAsSynonym"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-typeassynonym]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.StandardTokenizerFactory"/>
 +  <filter class="solr.TypeAsSynonymFilterFactory"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +With the example below, for a token "example.com" with type `<URL>`, the token emitted at the same position will be "\_type_<URL>":
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-typeassynonym-args]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer name="uax29URLEmail"/>
 +  <filter name="typeAsSynonym" prefix="_type_"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-typeassynonym-args]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <tokenizer class="solr.UAX29URLEmailTokenizerFactory"/>
 +  <filter class="solr.TypeAsSynonymFilterFactory" prefix="_type_"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +== Type Token Filter
 +
- This filter blacklists or whitelists a specified list of token types, assuming the tokens have type metadata associated with them.
++This filter denies or allows a specified list of token types, assuming the tokens have type metadata associated with them.
 +For example, the xref:tokenizers.adoc#uax29-url-email-tokenizer[UAX29 URL Email Tokenizer] emits "<URL>" and "<EMAIL>" typed tokens, as well as other types.
 +This filter would allow you to pull out only e-mail addresses from text as tokens, if you wish.
 +
 +*Factory class:* `solr.TypeTokenFilterFactory`
 +
 +*Arguments:*
 +
 +`types`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +Defines the path to a file of types to filter.
 +
 +`useWhitelist`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `false`
 +|===
 ++
 +If `true`, the file defined in `types` should be used as include list.
- If `false`, or undefined, the file defined in `types` is used as a blacklist.
++If `false`, or undefined, the file defined in `types` is used as a denylist.
 +
 +*Example:*
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-typetoken]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer>
 +  <filter name="typeToken" types="stoptypes.txt" useWhitelist="true"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-typetoken]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer>
 +  <filter class="solr.TypeTokenFilterFactory" types="stoptypes.txt" useWhitelist="true"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +== Word Delimiter Filter
 +
 +This filter splits tokens at word delimiters.
 +
 +.Word Delimiter Filter has been Deprecated
 +[WARNING]
 +====
 +Word Delimiter Filter has been deprecated in favor of Word Delimiter Graph Filter, which is required to produce a correct token graph so that e.g., phrase queries can work correctly.
 +====
 +
 +*Factory class:* `solr.WordDelimiterFilterFactory`
 +
 +For a full description, including arguments and examples, see the Word Delimiter Graph Filter below.
 +
 +== Word Delimiter Graph Filter
 +
 +This filter splits tokens at word delimiters.
 +
 +If you use this filter during indexing, you must follow it with a Flatten Graph Filter to squash tokens on top of one another like the Word Delimiter Filter, because the indexer can't directly consume a graph.
 +To get fully correct positional queries when tokens are split, you should instead use this filter at query time.
 +
 +Note: although this filter produces correct token graphs, it cannot consume an input token graph correctly.
 +
 +The rules for determining delimiters are determined as follows:
 +
 +* A change in case within a word: "CamelCase" -> "Camel", "Case".
 +This can be disabled by setting `splitOnCaseChange="0"`.
 +
 +* A transition from alpha to numeric characters or vice versa: "Gonzo5000" -> "Gonzo", "5000" "4500XL" -> "4500", "XL".
 +This can be disabled by setting `splitOnNumerics="0"`.
 +
 +* Non-alphanumeric characters (discarded): "hot-spot" -> "hot", "spot"
 +
 +* A trailing "'s" is removed: "O'Reilly's" -> "O", "Reilly"
 +
 +* Any leading or trailing delimiters are discarded: "--hot-spot--" -> "hot", "spot"
 +
 +*Factory class:* `solr.WordDelimiterGraphFilterFactory`
 +
 +*Arguments:*
 +
 +`generateWordParts`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `1`
 +|===
 ++
 +If non-zero, splits words at delimiters.
 +For example:"CamelCase", "hot-spot" -> "Camel", "Case", "hot", "spot"
 +
 +`generateNumberParts`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `1`
 +|===
 ++
 +If non-zero, splits numeric strings at delimiters:"1947-32" -> *"1947", "32"
 +
 +`splitOnCaseChange`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `1`
 +|===
 ++
 +If `0`, words are not split on camel-case changes:"BugBlaster-XL" -> "BugBlaster", "XL".
 +Example 1 below illustrates the default (non-zero) splitting behavior.
 +
 +`splitOnNumerics`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `1`
 +|===
 ++
 +If `0`, don't split words on transitions from alpha to numeric:"FemBot3000" -> "Fem", "Bot3000"
 +
 +`catenateWords`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `0`
 +|===
 ++
 +If non-zero, maximal runs of word parts will be joined: "hot-spot-sensor's" -> "hotspotsensor"
 +
 +`catenateNumbers`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `0`
 +|===
 ++
 +If non-zero, maximal runs of number parts will be joined: 1947-32" -> "194732"
 +
 +`catenateAll`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `0`
 +|===
 ++
 +If non-zero, runs of word and number parts will be joined: "Zap-Master-9000" -> "ZapMaster9000"
 +
 +`preserveOriginal`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `0`
 +|===
 ++
 +If non-zero, the original token is preserved: "Zap-Master-9000" -> "Zap-Master-9000", "Zap", "Master", "9000"
 +
 +`protected`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +The path to a file that contains a list of protected words that should be passed through without splitting.
 +
 +`stemEnglishPossessive`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `1`
 +|===
 ++
 +If `1`, strips the possessive `'s` from each subword.
 +
 +`types`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +The path to a file that contains *character \=> type* mappings, which enable customization of this filter's splitting behavior.
 +Recognized character types: `LOWER`, `UPPER`, `ALPHA`, `DIGIT`, `ALPHANUM`, and `SUBWORD_DELIM`.
 ++
 +The default for any character without a customized mapping is computed from Unicode character properties.
 +Blank lines and comment lines starting with '#' are ignored.
 +An example file:
 ++
 +[source,text]
 +----
 +# Don't split numbers at '$', '.' or ','
 +$ => DIGIT
 +. => DIGIT
 +\u002C => DIGIT
 +
 +# Don't split on ZWJ: https://en.wikipedia.org/wiki/Zero-width_joiner
 +\u200D => ALPHANUM
 +----
 +
 +*Example:*
 +
 +Default behavior.
 +The whitespace tokenizer is used here to preserve non-alphanumeric characters.
 +
 +[.dynamic-tabs]
 +--
 +[example.tab-pane#byname-filter-worddelimitergraph]
 +====
 +[.tab-label]*With name*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer name="whitespace"/>
 +  <filter name="wordDelimiterGraph"/>
 +  <filter name="flattenGraph"/> <!-- required on index analyzers after graph filters -->
 +</analyzer>
 +<analyzer type="query">
 +  <tokenizer name="whitespace"/>
 +  <filter name="wordDelimiterGraph"/>
 +</analyzer>
 +----
 +====
 +[example.tab-pane#byclass-filter-worddelimitergraph]
 +====
 +[.tab-label]*With class name (legacy)*
 +[source,xml]
 +----
 +<analyzer type="index">
 +  <tokenizer class="solr.WhitespaceTokenizerFactory"/>
 +  <filter class="solr.WordDelimiterGraphFilterFactory"/>
 +  <filter class="solr.FlattenGraphFilterFactory"/> <!-- required on index analyzers after graph filters -->
 +</analyzer>
 +<analyzer type="query">
 +  <tokenizer class="solr.WhitespaceTokenizerFactory"/>
 +  <filter class="solr.WordDelimiterGraphFilterFactory"/>
 +</analyzer>
 +----
 +====
 +--
 +
 +*In:* "hot-spot RoboBlaster/9000 100XL"
 +
 +*Tokenizer to Filter:* "hot-spot", "RoboBlaster/9000", "100XL"
 +
 +*Out:* "hot", "spot", "Robo", "Blaster", "9000", "100", "XL"
 +
 +*Example:*
 +
 +Do not split on case changes, and do not generate number parts.
 +Note that by not generating number parts, tokens containing only numeric parts are ultimately discarded.
 +
 +[source,xml]
 +----
 +<analyzer type="query">
 +  <tokenizer name="whitespace"/>
 +  <filter name="wordDelimiterGraph" generateNumberParts="0" splitOnCaseChange="0"/>
 +</analyzer>
 +----
 +
 +*In:* "hot-spot RoboBlaster/9000 100-42"
 +
 +*Tokenizer to Filter:* "hot-spot", "RoboBlaster/9000", "100-42"
 +
 +*Out:* "hot", "spot", "RoboBlaster", "9000"
 +
 +*Example:*
 +
 +Concatenate word parts and number parts, but not word and number parts that occur in the same token.
 +
 +[source,xml]
 +----
 +<analyzer type="query">
 +  <tokenizer name="whitespace"/>
 +  <filter name="wordDelimiterGraph" catenateWords="1" catenateNumbers="1"/>
 +</analyzer>
 +----
 +
 +*In:* "hot-spot 100+42 XL40"
 +
 +*Tokenizer to Filter:* "hot-spot"(1), "100+42"(2), "XL40"(3)
 +
 +*Out:* "hot"(1), "spot"(2), "hotspot"(2), "100"(3), "42"(4), "10042"(4), "XL"(5), "40"(6)
 +
 +*Example:*
 +
 +Concatenate all.
 +Word and/or number parts are joined together.
 +
 +[source,xml]
 +----
 +<analyzer type="query">
 +  <tokenizer name="whitespace"/>
 +  <filter name="wordDelimiterGraph" catenateAll="1"/>
 +</analyzer>
 +----
 +
 +*In:* "XL-4000/ES"
 +
 +*Tokenizer to Filter:* "XL-4000/ES"(1)
 +
 +*Out:* "XL"(1), "4000"(2), "ES"(3), "XL4000ES"(3)
 +
 +*Example:*
 +
 +Using a protected words list that contains "AstroBlaster" and "XL-5000" (among others).
 +
 +[source,xml]
 +----
 +<analyzer type="query">
 +  <tokenizer name="whitespace"/>
 +  <filter name="wordDelimiterGraph" protected="protwords.txt"/>
 +</analyzer>
 +----
 +
 +*In:* "FooBar AstroBlaster XL-5000 ==ES-34-"
 +
 +*Tokenizer to Filter:* "FooBar", "AstroBlaster", "XL-5000", "==ES-34-"
 +
 +*Out:* "FooBar", "FooBar", "AstroBlaster", "XL-5000", "ES", "34"
diff --cc solr/solr-ref-guide/modules/query-guide/pages/spatial-search.adoc
index 78e79ef,0000000..37aa580
mode 100644,000000..100644
--- a/solr/solr-ref-guide/modules/query-guide/pages/spatial-search.adoc
+++ b/solr/solr-ref-guide/modules/query-guide/pages/spatial-search.adoc
@@@ -1,733 -1,0 +1,733 @@@
 += Spatial Search
 +// Licensed to the Apache Software Foundation (ASF) under one
 +// or more contributor license agreements.  See the NOTICE file
 +// distributed with this work for additional information
 +// regarding copyright ownership.  The ASF licenses this file
 +// to you under the Apache License, Version 2.0 (the
 +// "License"); you may not use this file except in compliance
 +// with the License.  You may obtain a copy of the License at
 +//
 +//   http://www.apache.org/licenses/LICENSE-2.0
 +//
 +// Unless required by applicable law or agreed to in writing,
 +// software distributed under the License is distributed on an
 +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 +// KIND, either express or implied.  See the License for the
 +// specific language governing permissions and limitations
 +// under the License.
 +
 +Solr supports location data for use in spatial/geospatial searches.
 +
 +Using spatial search, you can:
 +
 +* Index points or other shapes
 +* Filter search results by a bounding box or circle or by other shapes
 +* Sort or boost scoring by distance between points, or relative area between rectangles
 +* Generate a 2D grid of facet count numbers for heatmap generation or point-plotting.
 +
 +There are four main field types available for spatial search:
 +
 +* `LatLonPointSpatialField`
 +* `PointType`
 +* `SpatialRecursivePrefixTreeFieldType` (RPT for short), including `RptWithGeometrySpatialField`, a derivative
 +* `BBoxField`
 +
 +`LatLonPointSpatialField` is the ideal field type for the most common use-cases for lat-lon point data.
 +RPT offers some more features for more advanced/custom use cases and options like polygons and heatmaps.
 +
 +`RptWithGeometrySpatialField` is for indexing and searching non-point data though it can do points too.
 +It can't do sorting/boosting.
 +
 +`BBoxField` is for indexing bounding boxes, querying by a box, specifying a search predicate (Intersects,Within,Contains,Disjoint,Equals), and a relevancy sort/boost like overlapRatio or simply the area.
 +
 +Some esoteric details that are not in this guide can be found in the https://cwiki.apache.org/confluence/display/solr/SpatialSearch[Spatial Search] section of the Solr Wiki.
 +
 +== LatLonPointSpatialField
 +
 +Here's how `LatLonPointSpatialField` (LLPSF) should usually be configured in the schema:
 +
 +[source,xml]
 +<fieldType name="location" class="solr.LatLonPointSpatialField" docValues="true"/>
 +
 +LLPSF supports toggling `indexed`, `stored`, `docValues`, and `multiValued`.
 +LLPSF internally uses a 2-dimensional Lucene "Points" (BDK tree) index when "indexed" is enabled (the default).
 +When "docValues" is enabled, a latitude and longitudes pair are bit-interleaved into 64 bits and put into Lucene DocValues.
 +The accuracy of the docValues data is about a centimeter.
 +
 +== Indexing Points
 +
 +For indexing geodetic points (latitude and longitude), supply it in "lat,lon" order (comma separated).
 +
 +For indexing non-geodetic points, it depends.
 +Use `x y` (a space) if RPT.
 +For PointType however, use `x,y` (a comma).
 +
 +If you'd rather use a standard industry format, Solr supports https://en.wikipedia.org/wiki/Well-known_text[WKT] and http://geojson.org/[GeoJSON].
 +However it's much bulkier than the raw coordinates for such simple data.
 +(Not supported by PointType)
 +
 +=== Indexing GeoJSON and WKT
 +
 +Using the `bin/post` tool:
 +
 +[source,text]
 +bin/post -type "application/json" -url "http://localhost:8983/solr/mycollection/update?format=geojson" /path/to/geojson.file
 +
 +The key parameter to pass in with your request is:
 +
 +`format`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `true`
 +|===
 ++
 +The format of the file to pass in.
 +Accepted values: `WKT` or `geojson`.
 +
 +== Searching with Query Parsers
 +
 +There are two spatial Solr "query parsers" for geospatial search: `geofilt` and `bbox`.
 +They take the following parameters:
 +
 +`d`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The radial distance, usually in kilometers.
 +RPT & BBoxField can set other units via the setting `distanceUnits`.
 +
 +`pt`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The center point using the format `lat,lon` if latitude & longitude.
 +Otherwise, "x,y" for PointType or "x y" for RPT field types.
 +
 +`sfield`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +A spatial indexed field.
 +
 +`score`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `none`
 +|===
 ++
 +If the query is used in a scoring context (e.g., as the main query in `q`), this xref:local-params.adoc[_local param_] determines what scores will be produced.
 +Advanced option; not supported by PointType.
 ++
 +Valid values are:
 +
 +* `none`: A fixed score of `1.0`.
 +* `kilometers`: distance in kilometers between the field value and the specified center point.
 +* `miles`: distance in miles between the field value and the specified center point.
 +* `degrees`: distance in degrees between the field value and the specified center point.
 +* `distance`: distance between the field value and the specified center point in the `distanceUnits` configured for this field.
 +* `recipDistance`: 1 / the distance.
 ++
 +[WARNING]
 +====
 +Don't use this for indexed non-point shapes (e.g., polygons).
 +The results will be erroneous.
 +And with RPT, it's only recommended for multi-valued point data, as the implementation doesn't scale very well and for single-valued fields, you should instead use a separate non-RPT field purely for distance sorting.
 +====
 ++
 +When used with `BBoxField`, additional options are supported:
 ++
 +* `overlapRatio`: The relative overlap between the indexed shape & query shape.
 +* `area`: haversine based area of the overlapping shapes expressed in terms of the `distanceUnits` configured for this field
 +* `area2D`: cartesian coordinates based area of the overlapping shapes expressed in terms of the `distanceUnits` configured for this field
 +
 +`filter`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `true`
 +|===
 ++
 +If you only want the query to score (with the above `score` local parameter), not filter, then set this local parameter to `false`.
 +Advanced option; not supported by PointType.
 +
 +=== geofilt
 +
 +The `geofilt` filter allows you to retrieve results based on the geospatial distance (AKA the "great circle distance") from a given point.
 +Another way of looking at it is that it creates a circular shape filter.
 +For example, to find all documents within five kilometers of a given lat/lon point, you could enter:
 +
 +[source,text]
 +&q=*:*&fq={!geofilt sfield=store}&pt=45.15,-93.85&d=5
 +
 +This filter returns all results within a circle of the given radius around the initial point:
 +
 +image::spatial-search/circle.png[5KM radius]
 +
 +
 +=== bbox
 +
 +The `bbox` filter is very similar to `geofilt` except it uses the _bounding box_ of the calculated circle.
 +See the blue box in the diagram below.
 +It takes the same parameters as geofilt.
 +
 +Here's a sample query:
 +
 +[source,text]
 +&q=*:*&fq={!bbox sfield=store}&pt=45.15,-93.85&d=5
 +
 +The rectangular shape is faster to compute and so it's sometimes used as an alternative to `geofilt` when it's acceptable to return points outside of the radius.
 +However, if the ideal goal is a circle but you want it to run faster, then instead consider using the RPT field and try a large `distErrPct` value like `0.1` (10% radius).
 +This will return results outside the radius but it will do so somewhat uniformly around the shape.
 +
 +image::spatial-search/bbox.png[Bounding box]
 +
 +[IMPORTANT]
 +====
 +When a bounding box includes a pole, the bounding box ends up being a "bounding bowl" (a _spherical cap_) that includes all values north of the lowest latitude of the circle if it touches the north pole (or south of the highest latitude if it touches the south pole).
 +====
 +
 +=== Filtering by an Arbitrary Rectangle
 +
 +Sometimes the spatial search requirement calls for finding everything in a rectangular area, such as the area covered by a map the user is looking at.
 +For this case, geofilt and bbox won't cut it.
 +This is somewhat of a trick, but you can use Solr's range query syntax for this by supplying the lower-left corner as the start of the range and the upper-right corner as the end of the range.
 +
 +Here's an example:
 +
 +[source,text]
 +&q=*:*&fq=store:[45,-94 TO 46,-93]
 +
 +For RPT and BBoxField, if you don't use lat-lon coordinates (`geo="false"`) then you must quote the points due to the space, e.g., `"x y"`.
 +
 +
 +=== Optimizing: Cache or Not
 +
 +It's most common to put a spatial query into an "fq" parameter – a filter query.
 +By default, Solr will cache the query in the filter cache.
 +
 +If you know the filter query (be it spatial or not) is fairly unique and not likely to get a cache hit then specify `cache="false"` as a local-param as seen in the following example.
 +The only spatial types which stand to benefit from this technique are those with docValues like LatLonPointSpatialField or BBoxField.
 +
 +[source,text]
 +&q=...mykeywords...&fq=...someotherfilters...&fq={!geofilt cache=false}&sfield=store&pt=45.15,-93.85&d=5
 +
 +== Distance Sorting or Boosting (Function Queries)
 +
 +There are four distance function queries:
 +
 +* `geodist`, see below, usually the most appropriate;
 +*  xref:function-queries.adoc#dist-function[`dist`], to calculate the p-norm distance between multi-dimensional vectors;
 +* xref:function-queries.adoc#hsin-function[`hsin`], to calculate the distance between two points on a sphere;
 +* xref:function-queries.adoc#sqedist-function[`sqedist`], to calculate the squared Euclidean distance between two points.
 +
 +For more information about these function queries, see the section on xref:function-queries.adoc[].
 +
 +=== geodist
 +
 +`geodist` is a distance function that takes three optional parameters: `(sfield,latitude,longitude)`.
 +You can use the `geodist` function to sort results by distance or score return results.
 +
 +For example, to sort your results by ascending distance, use a request like:
 +
 +[source,text]
 +&q=*:*&fq={!geofilt}&sfield=store&pt=45.15,-93.85&d=50&sort=geodist() asc
 +
 +To return the distance as the document score, use a request like:
 +
 +[source,text]
 +&q={!func}geodist()&sfield=store&pt=45.15,-93.85&sort=score+asc&fl=*,score
 +
 +== More Spatial Search Examples
 +
 +Here are a few more useful examples of what you can do with spatial search in Solr.
 +
 +=== Use as a Sub-Query to Expand Search Results
 +
 +Here we will query for results in Jacksonville, Florida, or within 50 kilometers of 45.15,-93.85 (near Buffalo, Minnesota):
 +
 +[source,text]
 +&q=*:*&fq=(state:"FL" AND city:"Jacksonville") OR {!geofilt}&sfield=store&pt=45.15,-93.85&d=50&sort=geodist()+asc
 +
 +=== Facet by Distance
 +
 +To facet by distance, you can use the `frange` query parser:
 +
 +[source,text]
 +&q=*:*&sfield=store&pt=45.15,-93.85&facet.query={!frange l=0 u=5}geodist()&facet.query={!frange l=5.001 u=3000}geodist()
 +
 +There are other ways to do it too, like using a `{!geofilt}` in each facet.query.
 +
 +=== Boost Nearest Results
 +
 +Using the xref:dismax-query-parser.adoc[] or xref:edismax-query-parser.adoc[], you can combine spatial search with the boost function to boost the nearest results:
 +
 +[source,text]
 +&q.alt=*:*&fq={!geofilt}&sfield=store&pt=45.15,-93.85&d=50&bf=recip(geodist(),2,200,20)&sort=score desc
 +
 +=== Returning Distance as a Field
 +
 +To return the distance as a pseudo field you can use the `geodist()` function in the field list.
 +
 +[source,text]
 +&fl=distance:geodist()
 +
 +== RPT
 +
 +RPT refers to either `SpatialRecursivePrefixTreeFieldType` (aka simply RPT) and an extended version:
 +  `RptWithGeometrySpatialField` (aka RPT with Geometry).
 +RPT offers several functional improvements over LatLonPointSpatialField:
 +
 +* Non-geodetic – geo=false general x & y (_not_ latitude and longitude) -- if desired
 +* Query by polygons and other complex shapes, in addition to circles & rectangles
 +* Ability to index non-point shapes (e.g., polygons) as well as points – see RptWithGeometrySpatialField
 +* Heatmap grid faceting
 +
 +RPT _shares_ various features in common with `LatLonPointSpatialField`.
 +Some are listed here:
 +
 +* Latitude/Longitude indexed point data; possibly multi-valued
 +* Fast filtering with `geofilt`, `bbox` filters, and range query syntax (dateline crossing is supported)
 +* Well-Known-Text (WKT) shape syntax (required for specifying polygons & other complex shapes), and GeoJSON too.
 +  In addition to indexing and searching, this works with the `wt=geojson` (GeoJSON Solr response-writer) and `[geo f=myfield]` (geo Solr document-transformer).
 +* Sort/boost via `geodist` -- _although not recommended_
 +
 +[IMPORTANT]
 +====
 +Although RPT supports distance sorting/boosting, it is so inefficient at doing this that it might be removed in the future.
 +Fortunately, you can use LatLonPointSpatialField _as well_ as RPT.
 +Use LLPSF for the distance sorting/boosting; it only needs to have docValues for this; the index attribute can be disabled as it won't be used.
 +====
 +
 +=== Schema Configuration for RPT
 +
 +To use RPT, the field type must be registered and configured in the collection's schema.
 +There are many options for this field type.
 +
 +`name`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The name of the field type.
 +
 +`class`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +This should be `solr.SpatialRecursivePrefixTreeFieldType`.
 +But be aware that the Lucene spatial module includes some other so-called "spatial strategies" other than RPT, notably TermQueryPT*, BBox, PointVector*, and SerializedDV.
- Solr requires a field type to parallel these in order to use them.
++Solr requires a corresponding field type in order to use those strategies.
 +The asterisked ones have them.
 +
 +`spatialContextFactory`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +This is a Java class name to an internal extension point governing support for shape definitions & parsing.
 +There are two built-in aliases for known implementations: `Geo3D` and `JTS`.
 +The default blank value does not support polygons.
 +
 +`geo`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `true`
 +|===
 ++
 +If `true`, latitude and longitude coordinates will be used and the mathematical model will generally be a sphere.
 +If `false`, the coordinates will be generic X & Y on a 2D plane using Euclidean/Cartesian geometry.
 +
 +`format`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `WKT`
 +|===
 ++
 +Defines the shape syntax/format to be used.
 +Defaults to `WKT` but `GeoJSON` is another popular format.
 +Spatial4j governs this feature and supports https://locationtech.github.io/spatial4j/apidocs/org/locationtech/spatial4j/io/package-frame.html[other formats].
 +If a given shape is parseable as "lat,lon" or "x y" then that is always supported.
 +
 +`distanceUnits`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +This is used to specify the units for distance measurements used throughout the use of this field.
 +This can be `degrees`, `kilometers` or `miles`.
 +It is applied to nearly all distance measurements involving the field: `maxDistErr`, `distErr`, `d`, `geodist`, and the `score` when score is `distance`, `area`, or `area2d`.
 +However, it doesn't affect distances embedded in WKT strings, (e.g., `BUFFER(POINT(200 10),0.2)`), which are still in degrees.
 ++
 +`distanceUnits` defaults to either `kilometers` if `geo` is `true`, or `degrees` if `geo` is `false`.
 ++
 +`distanceUnits` replaces the `units` attribute; which is now deprecated and mutually exclusive with this attribute.
 +
 +`distErrPct`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: _see description_
 +|===
 ++
 +Defines the default precision of non-point shapes (both index & query), as a fraction between `0.0` (fully precise) to `0.5`.
 +The closer this number is to zero, the more accurate the shape will be.
 +However, more precise indexed shapes use more disk space and take longer to index.
 ++
 +Bigger `distErrPct` values will make queries faster but less accurate.
 +At query time this can be overridden in the query syntax, such as to `0.0` so as to not approximate the search shape.
 +The default for the RPT field is `0.025`.
 ++
 +NOTE: For RPTWithGeometrySpatialField (see below), there's always complete accuracy with the serialized geometry and so this doesn't control accuracy so much as it controls the trade-off of how big the index should be.
 +`distErrPct` defaults to `0.15` for that field.
 +
 +`maxDistErr`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: _see description_
 +|===
 ++
 +Defines the highest level of detail required for indexed data.
 +If left blank, the default is one meter – just a bit less than 0.000009 degrees.
 +This setting is used internally to compute an appropriate maxLevels (see below).
 +
 +`worldBounds`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +Defines the valid numerical ranges for x and y, in the format of `ENVELOPE(minX, maxX, maxY, minY)`.
 +If `geo="true"`, the standard lat-lon world boundaries are assumed.
 +If `geo=false`, you should define your boundaries.
 +
 +`distCalculator`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: _see description_
 +|===
 ++
 +Defines the distance calculation algorithm.
 +If `geo=true`, `haversine` is the default.
 +If `geo=false`, `cartesian` will be the default.
 +Other possible values are `lawOfCosines`, `vincentySphere` and `cartesian^2`.
 +
 +`prefixTree`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: _see description_
 +|===
 ++
 +Defines the spatial grid implementation.
 +Since a PrefixTree (such as RecursivePrefixTree) maps the world as a grid, each grid cell is decomposed to another set of grid cells at the next level.
 ++
 +If `geo=true` then the default prefix tree is `geohash`, otherwise it's `quad`.
 +Geohash has 32 children at each level, quad has 4.
 +Geohash can only be used for `geo=true` as it's strictly geospatial.
 ++
 +A third choice is `packedQuad`, which is generally more efficient than `quad`, provided there are many levels -- perhaps 20 or more.
 +
 +`maxLevels`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +Sets the maximum grid depth for indexed data.
 +Instead, it's usually more intuitive to compute an appropriate maxLevels by specifying `maxDistErr`.
 +
 +*_And there are others:_* `normWrapLongitude`, `datelineRule`, `validationRule`, `autoIndex`, `allowMultiOverlap`, `precisionModel`.
 +For further info, see notes below about `spatialContextFactory` implementations referenced above, especially the link to the JTS based one.
 +
 +=== Standard Shapes
 +
 +The RPT field types support a set of standard shapes:
 +points, circles (aka buffered points), envelopes (aka rectangles or bounding boxes), line strings, polygons, and "multi" variants of these.
 +The envelopes and line strings are Euclidean/cartesian (flat 2D) shapes.
 +Underlying Solr is the Spatial4j library which implements them.
 +To support other shapes, you can configure the `spatialContextFactory` attribute on the field type to reference other options.
 +Two are available: JTS and Geo3D.
 +
 +=== JTS and Polygons (flat)
 +
 +The https://github.com/locationtech/jts[JTS Topology Suite] is a popular computational geometry library with a Euclidean/cartesian (flat 2D) model.
 +It supports a variety of shapes including polygons, buffering shapes, and some invalid polygon repair fall-backs.
 +With the help of Spatial4j, included with Solr, the polygons support dateline (anti-meridian) crossing.
 +You must download it (a JAR file) and put that in a special location internal to Solr:  `SOLR_INSTALL/server/solr-webapp/webapp/WEB-INF/lib/`.
 +You can readily download it here: https://mvnrepository.com/artifact/org.locationtech.jts/jts-core/1.15.0.
 +_It will not work if placed in other more typical Solr lib directories, unfortunately._
 +
 +Set the `spatialContextFactory` attribute on the field type to `JTS`.
 +
 +When activated, there are additional configuration attributes available; see
 +  https://locationtech.github.io/spatial4j/apidocs/org/locationtech/spatial4j/context/jts/JtsSpatialContextFactory.html[org.locationtech.spatial4j.context.jts.JtsSpatialContextFactory]
 +  for the Javadocs, and remember to look at the superclass's options as well.
 +One option in particular you should most likely enable is `autoIndex` (i.e., use JTS's PreparedGeometry) as it's been shown to be a major performance boost for non-trivial polygons.
 +
 +[source,xml]
 +----
 +<fieldType name="location_rpt"   class="solr.SpatialRecursivePrefixTreeFieldType"
 +               spatialContextFactory="JTS"
 +               autoIndex="true"
 +               validationRule="repairBuffer0"
 +               distErrPct="0.025"
 +               maxDistErr="0.001"
 +               distanceUnits="kilometers" />
 +----
 +
 +Once the field type has been defined, define a field that uses it.
 +
 +Here's an example polygon query for a field "geo" that can be either solr.SpatialRecursivePrefixTreeFieldType or RptWithGeometrySpatialField:
 +
 +[source,plain]
 +&q=*:*&fq={!field f=geo}Intersects(POLYGON((-10 30, -40 40, -10 -20, 40 20, 0 0, -10 30)))
 +
 +Inside the parenthesis following the search predicate is the shape definition.
 +The format of that shape is governed by the `format` attribute on the field type, defaulting to WKT.
 +If you prefer GeoJSON, you can specify that instead.
 +
 +Beyond this Reference Guide and Spatila4j's docs, there are some details that remain at the Solr Wiki at https://cwiki.apache.org/confluence/display/solr/SolrAdaptersForLuceneSpatial4.
 +
 +=== Geo3D and Polygons (on the ellipsoid)
 +
 +Geo3D is the colloquial name of the Lucene spatial-3d module, included with Solr.
 +It's a computational geometry library implementing a variety of shapes (including polygons) on a sphere or WGS84 ellipsoid.
 +Geo3D is particularly suited for spatial applications where the geometries cover large distances across the globe or are near the poles.
 +Geo3D is named as-such due to its internal implementation that uses geocentric coordinates (X,Y,Z),
 +  *not* for 3-dimensional geometry, which it does not support.
 +Despite these internal details, you still supply latitude and longitude as you would normally in Solr.
 +
 +Set the `spatialContextFactory` attribute on the field type to `Geo3D`.
 +
 +[source,xml]
 +----
 +<fieldType name="geom"
 +  class="solr.SpatialRecursivePrefixTreeFieldType"
 +  spatialContextFactory="Geo3D"
 +  prefixTree="s2"
 +  planetModel="WGS84"/><!-- or "sphere" -->
 +----
 +
 +Once the field type has been defined, define a field that uses it.
 +
 +The `prefixTree="s2"` setting is optional and only possible with Geo3D.
 +It was developed with Geo3D in mind to be more efficient than the other grids.
 +
 +IMPORTANT: When using Geo3D, the order of polygon points matters!
 +You must follow the so-called "right hand rule": the exterior ring must be counter-clockwise order and the interior holes must be clockwise.
 +If the order is wrong then the interpretation is inverted, thus the polygon will be interpreted as encompassing most of the globe.
 +
 +=== RptWithGeometrySpatialField
 +
 +The `RptWithGeometrySpatialField` field type is a derivative of `SpatialRecursivePrefixTreeFieldType` that also stores the original geometry internally in Lucene DocValues, which it uses to achieve accurate search.
 +It can also be used for indexed point fields.
 +The Intersects predicate (the default) is particularly fast, since many search results can be returned as an accurate hit without requiring a geometry check.
 +This field type is configured just like RPT except that the default `distErrPct` is 0.15 (higher than 0.025) because the grid squares are purely for performance and not to fundamentally represent the shape.
 +
 +An optional in-memory cache can be defined in `solrconfig.xml`, which should be done when the data tends to have shapes with many vertices.
 +Assuming you name your field "geom", you can configure an optional cache in `solrconfig.xml` by adding the following – notice the suffix of the cache name:
 +
 +[source,xml]
 +----
 +<cache name="perSegSpatialFieldCache_geom"
 +           class="solr.CaffeineCache"
 +           size="256"
 +           initialSize="0"
 +           autowarmCount="100%"
 +           regenerator="solr.NoOpRegenerator"/>
 +----
 +
 +When using this field type, you will likely _not_ want to mark the field as stored because it's redundant with the DocValues data and surely larger because of the formatting (be it WKT or GeoJSON).
 +To retrieve the spatial data in search results from DocValues, use the xref:document-transformers.adoc#geo-geospatial-formatter[`[geo]` transformer].
 +
 +=== Heatmap Faceting
 +
 +The RPT field supports generating a 2D grid of facet counts for documents having spatial data in each grid cell.
 +For high-detail grids, this can be used to plot points, and for lesser detail it can be used for heatmap generation.
 +The grid cells are determined at index-time based on RPT's configuration.
 +At facet counting time, the indexed cells in the region of interest are traversed and a grid of counters corresponding to each cell are incremented.
 +Solr can return the data in a straight-forward 2D array of integers or in a PNG which compresses better for larger data sets but must be decoded.
 +
 +The heatmap feature is accessible both from Solr's standard faceting feature and the xref:json-facet-api.adoc#heatmap-facet[JSON Facet API].
 +We'll proceed now with standard faceting.
 +As a part of faceting, it supports the `key` local parameter as well as excluding tagged filter queries, just like other types of faceting do.
 +This allows multiple heatmaps to be returned on the same field with different filters.
 +
 +`facet`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `false`
 +|===
 ++
 +Set to `true` to enable standard faceting.
 +
 +`facet.heatmap`::
 ++
 +[%autowidth,frame=none]
 +|===
 +s|Required |Default: none
 +|===
 ++
 +The field name of type RPT.
 +
 +`facet.heatmap.geom`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +The region to compute the heatmap on, specified using the rectangle-range syntax or WKT.
 +It defaults to the world.
 +ex: `["-180 -90" TO "180 90"]`.
 +
 +`facet.heatmap.gridLevel`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: _see description_
 +|===
 ++
 +A specific grid level, which determines how big each grid cell is.
 +Defaults to being computed via `distErrPct` (or `distErr`).
 +
 +`facet.heatmap.distErrPct`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `0.15`
 +|===
 ++
 +A fraction of the size of geom used to compute gridLevel.
 +It's computed the same as a similarly named parameter for RPT.
 +
 +`facet.heatmap.distErr`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: none
 +|===
 ++
 +A cell error distance used to pick the grid level indirectly.
 +It's computed the same as a similarly named parameter for RPT.
 +
 +`facet.heatmap.format`::
 ++
 +[%autowidth,frame=none]
 +|===
 +|Optional |Default: `ints2D`
 +|===
 ++
 +The format, either `ints2D` or `png`.
 +
 +[TIP]
 +====
 +You'll experiment with different `distErrPct` values (probably 0.10 - 0.20) with various input geometries till the default size is what you're looking for.
 +The specific details of how it's computed aren't important.
 +For high-detail grids used in point-plotting (loosely one cell per pixel), set `distErr` to be the number of decimal-degrees of several pixels or so of the map being displayed.
 +Also, you probably don't want to use a geohash-based grid because the cell orientation between grid levels flip-flops between being square and rectangle.
 +Quad is consistent and has more levels, albeit at the expense of a larger index.
 +====
 +
 +Here's some sample output in JSON (with "..." inserted for brevity):
 +
 +[source,plain]
 +----
 +{gridLevel=6,columns=64,rows=64,minX=-180.0,maxX=180.0,minY=-90.0,maxY=90.0,
 +counts_ints2D=[[0, 0, 2, 1, ....],[1, 1, 3, 2, ...],...]}
 +----
 +
 +The output shows the gridLevel which is interesting since it's often computed from other parameters.
 +If an interface being developed allows an explicit resolution increase/decrease feature then subsequent requests can specify the gridLevel explicitly.
 +
 +The `minX`, `maxX`, `minY`, `maxY` reports the region where the counts are.
 +This is the minimally enclosing bounding rectangle of the input `geom` at the target grid level.
 +This may wrap the dateline.
 +The `columns` and `rows` values are how many columns and rows that the output rectangle is to be divided by evenly.
 +Note: Don't divide an on-screen projected map rectangle evenly to plot these rectangles/points since the cell data is in the coordinate space of decimal degrees if geo=true or whatever units were given if geo=false.
 +This could be arranged to be the same as an on-screen map but won't necessarily be.
 +
 +The `counts_ints2D` key has a 2D array of integers.
 +The initial outer level is in row order (top-down), then the inner arrays are the columns (left-right).
 +If any array would be all zeros, a null is returned instead for efficiency reasons.
 +The entire value is null if there is no matching spatial data.
 +
 +If `format=png` then the output key is `counts_png`.
 +It's a base-64 encoded string of a 4-byte PNG.
 +The PNG logically holds exactly the same data that the ints2D format does.
 +Note that the alpha channel byte is flipped to make it easier to view the PNG for diagnostic purposes, since otherwise counts would have to exceed 2^24 before it becomes non-opague.
 +Thus counts greater than this value will become opaque.
 +
 +== BBoxField
 +
 +The `BBoxField` field type indexes a single rectangle (bounding box) per document field and supports searching via a bounding box.
 +It supports most spatial search predicates, it has enhanced relevancy modes based on the overlap or area between the search rectangle and the indexed rectangle.
 +It's particularly useful for its relevancy modes.
 +To configure it in the schema, use a configuration like this:
 +
 +[source,xml]
 +----
 +<field name="bbox" type="bbox" />
 +
 +<fieldType name="bbox" class="solr.BBoxField"
 +           geo="true" distanceUnits="kilometers" numberType="pdouble" />
 +<fieldType name="pdouble" class="solr.DoublePointField" docValues="true"/>
 +----
 +
 +BBoxField is actually based off of 4 instances of another field type referred to by numberType.
 +It also uses a boolean to flag a dateline cross.
 +Assuming you want to use the relevancy feature, docValues is required.
 +Some of the attributes are in common with the RPT field like geo, units, worldBounds, and spatialContextFactory because they share some of the same spatial infrastructure.
 +
 +To index a box, add a field value to a bbox field that's a string in the WKT/CQL ENVELOPE syntax.
 +Example: `ENVELOPE(-10, 20, 15, 10)` which is minX, maxX, maxY, minY order.
 +The parameter ordering is unintuitive but that's what the spec calls for.
 +Alternatively, you could provide a rectangular polygon in WKT (or GeoJSON if you set set `format="GeoJSON"`).
 +
 +To search, you can use the `{!bbox}` query parser, or the range syntax e.g., `[10,-10 TO 15,20]`, or the ENVELOPE syntax wrapped in parenthesis with a leading search predicate.
 +The latter is the only way to choose a predicate other than Intersects.
 +For example:
 +
 +[source,plain]
 +&q={!field f=bbox}Contains(ENVELOPE(-10, 20, 15, 10))
 +
 +
 +Now to sort the results by one of the relevancy modes, use it like this:
 +
 +[source,plain]
 +&q={!field f=bbox score=overlapRatio}Intersects(ENVELOPE(-10, 20, 15, 10))
 +
 +
 +The `score` local parameter can be one of `overlapRatio`, `area`, and `area2D`.
 +`area` scores by the document area using surface-of-a-sphere (assuming `geo=true`) math, while `area2D` uses simple width * height.
 +`overlapRatio` computes a [0-1] ranged score based on how much overlap exists relative to the document's area and the query area.
 +The javadocs of {lucene-javadocs}/spatial-extras/org/apache/lucene/spatial/bbox/BBoxOverlapRatioValueSource.html[BBoxOverlapRatioValueSource] have more info on the formula.
 +There is an additional parameter `queryTargetProportion` that allows you to weight the query side of the formula to the index (target) side of the formula.
 +You can also use `&debug=results` to see useful score computation info.
diff --cc solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-9.adoc
index 4d7e0d6,0000000..48c6e6a
mode 100644,000000..100644
--- a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-9.adoc
+++ b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-9.adoc
@@@ -1,248 -1,0 +1,251 @@@
 += Major Changes in Solr 9
 +// Licensed to the Apache Software Foundation (ASF) under one
 +// or more contributor license agreements.  See the NOTICE file
 +// distributed with this work for additional information
 +// regarding copyright ownership.  The ASF licenses this file
 +// to you under the Apache License, Version 2.0 (the
 +// "License"); you may not use this file except in compliance
 +// with the License.  You may obtain a copy of the License at
 +//
 +//   http://www.apache.org/licenses/LICENSE-2.0
 +//
 +// Unless required by applicable law or agreed to in writing,
 +// software distributed under the License is distributed on an
 +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 +// KIND, either express or implied.  See the License for the
 +// specific language governing permissions and limitations
 +// under the License.
 +
 +Solr 9.0 is a major new release of Solr.
 +
 +This page highlights the biggest changes, including new features you may want to be aware of, and changes in default behavior and deprecated features that have been removed.
 +
 +== Solr 9 Upgrade Planning
 +
 +Before starting an upgrade to Solr 9, please take the time to review all information about changes from the version you are currently on up to Solr 9.
 +
 +You should also consider all changes that have been made to Solr in any version you have not upgraded to already. For example, if you are currently using Solr 8.1, you should review changes made in all subsequent 8.x releases in addition to changes for 9.0.
 +
 +A thorough review of the list in Major Changes in Earlier 8.x Versions as well as the {solr-javadocs}/changes//Changes.html[CHANGES.txt] in your Solr instance will help you plan your migration to Solr 9.
 +
 +=== Upgrade Prerequisites
 +
 +* LUCENE-8738: Move to Java 11 as minimum Java version.
 +
 +* Upgrade all collections in `stateFormat=1` to `stateFormat=2` *before* upgrading to Solr 9, as Solr 9 does not support the older format and no longer supports migrating collections from the older format to the current format (previously known as stateFormat=2).
 +Upgrade is to be done using Collection API MIGRATESTATEFORMAT action using a previous version of Solr.
 +See for example https://solr.apache.org/guide/8_8/cluster-node-management.html#migratestateforma[Solr 8.8 Ref Guide].
 +// Can't link directly to .adoc file, need to link to 8.something ref guide as MIGRATESTATEFORMAT no longer exists in 9.0.
 +
 +* SOLR-12823: Remove `/clusterstate.json` support, i.e., support for collections created with `stateFormat=1` as well as support for Collection API MIGRATESTATEFORMAT action.
 +Also removes support for cluster property `legacyCloud` (as if always false now).
 +
 +* If you're using a SolrJ CloudClient to connect to your Solr cluster, you must be using SolrJ version 8.10 or higher (8.x) when upgrading your SolrCloud from 8.x to 9.x.
 +Otherwise, SolrJ will not be able to connect to the cluster once it has upgraded to Solr 9.
 +Once you have upgraded all Solr clusters that the client is connecting to, you can upgrade the SolrJ client to 9.x.
 +
 +* If you're using Solr in standalone mode with the xref:query-guide:query-elevation-component.adoc[] with it's elevation file in the data directory, you'll have to move it to the xref:configuration-guide:config-sets.adoc[Configset] instead.
 +The only reason QEC supported the data directory was to support loading its changes on a commit instead of a more expensive core reload.
 +That feature now works from the configset dir too.
 +SolrCloud doesn't support that but may sometime.
 +
 +=== Rolling Upgrades
 +
 +* SOLR-14702: All references to "master" and "slave" were replaced in the code with "leader" and "follower".
 +This includes API calls for the replication handler and metrics.
 +For rolling upgrades into 9.0, you need to be on Solr version 8.7 or greater. Some metrics also changed, alerts and  monitors on Solr KPIs that mention "master" or "slave" will also now be "leader" and "follower"
 +
 +=== Reindexing After Upgrade
 +
 +In Solr 8, it's possible to add docValues to a schema without re-indexing via `UninvertDocValuesMergePolicy`, an advanced/expert utility.
 +Due to changes in Lucene 9, that isn't possible any more; the component was removed.
 +If re-indexing is too onerous, use this mechanism in Solr 8.
 +
 +== Solr 9.0 Raw Notes
 +
 +_(raw; not yet edited)_
 +
 +
 +* SOLR-13671: Allow 'var' keyword in Java sources
 +
 +* SOLR-12055 introduces async logging by default. There's a small window where log messages may be lost in the event of some hard crash.
 +Switch back to synchronous logging if this is unacceptable, see comments in the log4j2 configuration files (log4j2.xml by default).
 +
 +* SOLR-13323: The unused package org.apache.solr.internal.csv.writer and associated classes/tests that were easily confused with but not used by org.apache.solr.response.CSVWriter (or any other code) have been removed
 +
 +* SOLR-13854, SOLR-13858: SolrMetricProducer / SolrInfoBean APIs have changed and third-party components that implement these APIs need to be updated.
 +
 +* SOLR-14344: Remove Deprecated HttpSolrClient.RemoteSolrException and HttpSolrClient.RemoteExcecutionException.
 +All the usages are replaced by BaseHttpSolrClient.RemoteSolrException and BaseHttpSolrClient.RemoteExcecutionException.
 +
 +* SOLR-15409: Zookeeper client libraries upgraded to 3.7.0, which may not be compatible with your existing server installations
 +
++* SOLR-15809: Get rid of blacklist/whitelist terminology. JWTAuthPlugin parameter `algWhitelist` is now `algAllowlist`. The old parameter will still
++  work in 9.x. Environment variables `SOLR_IP_WHITELIST` and `SOLR_IP_BLACKLIST` are no longer supported, but replaced with `SOLR_IP_ALLOWLIST` and `SOLR_IP_DENYLIST`.
++
 +
 +== New Features & Enhancements
 +
 +* Replica placement plugins
 +
 +* Rate limiting and task management
 +
 +* Certificate Auth Plugin
 +
 +* SQL Query interface in UI
 +
 +== Configuration and Default Parameter Changes
 +
 +* SOLR-7530: TermsComponent's JSON response format was changed so that "terms" property carries per field arrays by default regardless of distrib, terms.list, terms.ttf parameters.
 +This affects JSON based response format but not others
 +
 +* SOLR-14036: Implicit /terms handler now returns terms across all shards in SolrCloud instead of only the local core.
 +Users/apps may be assuming the old behavior.
 +A request can be modified via the standard distrib=false param to only use the local core receiving the request.
 +
 +* SOLR-13783: In situations where a NamedList must be output as plain text, commas between key-value pairs will now be followed by a space (e.g., {shape=square, color=yellow} rather than {shape=square,color=yellow}) for consistency with other `java.util.Map` implementations based on `AbstractMap`.
 +
 +* SOLR-11725: JSON aggregations uses corrected sample formula to compute standard deviation and variance.
 +The computation of stdDev and variance in JSON aggregation is same as StatsComponent.
 +
 +* SOLR-14012: unique and hll aggregations always returns long value irrespective of standalone or solcloud
 +
 +* SOLR-11775: Return long value for facet count in Json Facet module irrespective of number of shards
 +
 +* SOLR-15276: V2 API call to look up async request status restful style of "/cluster/command-status/1000" instead of "/cluster/command-status?requestid=1000".
 +
 +* SOLR-14972: The default port of prometheus exporter has changed from 9983 to 8989, so you may need to adjust your configuration after upgrade.
 +
 +* SOLR-15471: The language identification "whitelist" configuration is now an "allowlist" to better convey the meaning of the property
 +
 +* SOLR-12891: MacroExpander will no longer will expand URL parameters inside of the 'expr' parameter (used by streaming expressions).
 +Additionally, users are advised to use the 'InjectionDefense' class when constructing streaming expressions that include user supplied data to avoid risks similar to SQL injection.
 +The legacy behavior of expanding the 'expr' parameter can be reinstated with -DStreamingExpressionMacros=true passed to the JVM at startup
 +
 +* SOLR-13324: URLClassifyProcessor#getCanonicalUrl now throws MalformedURLException rather than hiding it.
 +Although the present code is unlikely to produce such an exception it may be possible in future changes or in subclasses.
 +Currently this change should only effect compatibility of custom code overriding this method.
 +
 +* SOLR-14510: The `writeStartDocumentList` in `TextResponseWriter` now receives an extra boolean parameter representing the "exactness" of the `numFound` value (exact vs approximation).
 +Any custom response writer extending `TextResponseWriter` will need to implement this abstract method now (instead previous with the same name but without the new boolean parameter).
 +
 +=== solr.xml maxBooleanClauses now enforced recursively
 +
 +Lucene 9.0 has additional safety checks over previous versions that impact how the `solr.xml` global xref:configuration-guide:configuring-solr-xml#global-maxbooleanclauses[`maxBooleanClauses`] option is enforced.
 +
 +In previous versios of Solr, this option was a hard limit on the number of clauses in any `BooleanQuery` object - but it was only enforced for the _direct_ clauses.
 +Starting with Solr 9, this global limit is now also enforced against the total number of clauses in a _nested_ query structure.
 +
 +Users who upgrade from prior versions of Solr may find that some requests involving complex internal query structures (Example: long query strings using `edismax` with many `qf` and `pf` fields that include query time synonym expansion) which worked in the past now hit this limit and fail.
 +
 +User's in this situation are advised to consider the complexity f their queries/configuration, and increase the value of xref:configuration-guide:configuring-solr-xml#global-maxbooleanclauses[`maxBooleanClauses`] if warranted.
 +
 +=== Log4J configuration & Solr MDC values
 +
 +link:http://www.slf4j.org/apidocs/org/slf4j/MDC.html[MDC] values that Solr sets for use by Logging calls (such as the collection name, shard name, replica name, etc...) have been modified to now be "bare" values, with out the special single character prefixes that were included in past version.
 +For example: In 8.x Log messages for a collection named "gettingstarted" would have an MDC value with a key `collection` mapped to a value of `c:gettingstarted`, in 9.x the value will simply be `gettingstarted`.
 +
 +Solr's default `log4j2.xml` configuration file has been modified to prepend these same prefixes to MDC values when included in Log messages as part of the `<PatternLayout/>`.
 +Users who have custom logging configurations that wish to ensure Solr 9.x logs are consistently formatted after upgrading will need to make similar changes to their logging configuration files.  See  link:https://issues.apache.org/jira/browse/SOLR-15630[SOLR-15630] for more details.
 +
 +
 +=== base_url removed from stored state
 +
 +If you're able to upgrade SolrJ to 8.8.x for all of your client applications, then you can set `-Dsolr.storeBaseUrl=false` (introduced in Solr 8.8.1) to better align the stored state in Zookeeper with future versions of Solr; as of Solr 9.x, the `base_url` will no longer be persisted in stored state.
 +However, if you are not able to upgrade SolrJ to 8.8.x for all client applications, then you should set `-Dsolr.storeBaseUrl=true` so that Solr will continue to store the `base_url` in Zookeeper.
 +For background, see: SOLR-12182 and SOLR-15145.
 +
 +Support for the `solr.storeBaseUrl` system property will be removed in Solr 10.x and `base_url` will no longer be stored.
 +
 +* Solr's distributed tracing no longer incorporates a special `samplePercentage` SolrCloud cluster property.
 +Instead, consult the documentation for the tracing system you use on how to sample the traces.
 +Consequently, if you use a Tracer at all, you will always have traces and thus trace IDs in logs.
 +What percentage of them get reported to a tracing server is up to you.
 +
 +* JaegerTracerConfigurator no longer recognizes any configuration in solr.xml.
 +  It is now completely configured via System properties and/or Environment variables as documented by Jaeger.
 +
 +=== Schema Changes
 +
 +* `LegacyBM25SimilarityFactory` has been removed.
 +
 +* SOLR-13593 SOLR-13690 SOLR-13691: Allow to look up analyzer components by their SPI names in field type configuration.
 +
 +=== Authentication & Security Changes
 +
 +* The property `blockUnknown` in the BasicAuthPlugin and the JWTAuthPlugin now defaults to `true`.
 +This change is backward incompatible.
 +If you need the pre-9.0 default behavior, you need to explicitly set `blockUnknown:false` in `security.json`.
 +
 +* The allow-list defining allowed URLs for the `shards` parameter is not in the `shardHandler` configuration anymore. It is defined by the `allowUrls` top-level property of the `solr.xml` file. For more information, see xref:configuration-guide:configuring-solr-xml.adoc#allow-urls[Format of solr.allowUrls] documentation.
 +
 +* SOLR-13985: Solr's Jetty now binds to localhost network interface by default for better out of the box security.
 +Administrators that need Solr exposed more broadly can change the SOLR_JETTY_HOST property in their Solr include (solr.in.sh/solr.in.cmd) file.
 +
 +* SOLR-14147: Solr now runs with the java security manager enabled by default. Administrators that need to run Solr with Hadoop will need to disable this feature by setting SOLR_SECURITY_MANAGER_ENABLED=false in the environment or in one of the Solr init scripts. Other features in Solr could also break. (Robert Muir, marcussorealheis)
 +
 +* SOLR-14118: Solr embedded zookeeper only binds to localhost by default.
 +This embedded zookeeper should not be used in production.
 +If you rely upon the previous behavior, then you can change the clientPortAddress in solr/server/solr/zoo.cfg
 +
 +=== Contrib Changes
 +
 +* SOLR-14067: `StatelessScriptUpdateProcessorFactory` moved to `contrib/scripting` package instead of shipping as part of Solr, due to security concerns.
 +Renamed to ScriptUpdateProcessorFactory for simpler name.
 +
 +* SOLR-15121: `XSLTResponseWriter` moved to `contrib/scripting` package instead
 +of shipping as part of Solr, due to security concerns.
 +
 +* SOLR-14926: `contrib/clustering` back and rewritten
 +
 +* SOLR-14912: Cleaned up solr-extraction contrib to produce solr-extraction-* jar (instead of solr-cell-*). (Dawid Weiss)
 +
 +== Deprecations & Removed Features
 +
 +The following list of features have been permanently removed from Solr:
 +
 +* SOLR-14656: Autoscaling framework removed.
 +This includes:
 +** Autoscaling, policy, triggers etc.
 +** withCollection handling (SOLR-14964)
 +** UTILIZENODE command
 +** Sim framework
 +** Suggestions tab in UI
 +** Reference guide pages for autoscaling
 +** autoAddReplicas feature
 +
 +* SOLR-14783: Data Import Handler (DIH) has been removed from Solr.
 +The community package is available at: https://github.com/rohitbemax/dataimporthandler
 +
 +* SOLR-14792: VelocityResponseWriter has been removed from Solr.
 +This encompasses all previous included `/browse` and `wt=velocity` examples.
 +This feature has been migrated to an installable package at https://github.com/erikhatcher/solr-velocity
 +
 +* SOLR-13817: Legacy SolrCache implementations (LRUCache, LFUCache, FastLRUCache) have been removed.
 +Users have to modify their existing configurations to use CaffeineCache instead. (ab)
 +
 +* CDCR
 +
 +* Storing indexes and backups in HDFS
 +
 +* Solr's blob store
 +** SOLR-14654: plugins cannot be loaded using "runtimeLib=true" option. Use the package manager to use and load plugins
 +
 +* Metrics History
 +
 +* SOLR-15470: The binary distribution no longer contains test-framework jars.
 +
 +* SOLR-15203: Remove the deprecated `jwkUrl` in favour of `jwksUrl` when configuring JWT authentication.
 +
 +* SOLR-12847: maxShardsPerNode parameter has been removed because it was broken and inconsistent with other replica placement strategies.
 +Other relevant placement strategies should be used instead, such as autoscaling policy or rules-based placement.
 +
 +* SOLR-14092: Deprecated BlockJoinFacetComponent and BlockJoinDocSetFacetComponent are removed.
 +Users are encouraged to migrate to uniqueBlock() in JSON Facet API.  (Mikhail Khludnev)
 +
 +* SOLR-13596: Deprecated GroupingSpecification methods are removed.
 +
 +* SOLR-11266: default Content-Type override for JSONResponseWriter from `_default` configSet is removed.
 +Example has been provided in `sample_techproducts_configs` to override content-type.
 +
 +* `min_rf` deprecated in 7.x