Skip to content

Commit

Permalink
Merge pull request #76 from silverstripe/feature/enterprise-search
Browse files Browse the repository at this point in the history
MAJOR: Move to new Enterprise Search dependency
  • Loading branch information
andrewandante authored Aug 16, 2022
2 parents 06832e8 + d94190c commit b1ed1e9
Show file tree
Hide file tree
Showing 107 changed files with 3,928 additions and 2,407 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: CI

on:
push:
pull_request:

jobs:
ci:
uses: silverstripe/gha-ci/.github/workflows/ci.yml@v1
with:
dynamic_matrix: false
extra_jobs: |
- php: 8.0
phplinting: true
- php: 8.0
phpunit: true
- php: 8.0
db: mysql57pdo
phpunit: true
- php: 8.0
db: mysql80
phpunit: true
- php: 8.1
phpunit: true
25 changes: 0 additions & 25 deletions .travis.yml

This file was deleted.

10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

This module for Silverstripe CMS provides a set of abstraction layers that integrate the
CMS with a search-as-a-service provider, such as Elastic or Algolia. Out of the box, it
supports indexing DataObjects with Elastic AppSearch, but can be extended to work with
supports indexing DataObjects with Elastic EnterpriseSearch, but can be extended to work with
other sources of content and/or service providers.

This module does not provide any frontend functionality such as UI or querying APIs.
Expand All @@ -21,9 +21,11 @@ composer require "silverstripe/silverstripe-search-service"

## Requirements

* silverstripe/framework 4.4+
* silverstripe/versioned
* symbiote/silverstripe-queuedjobs
* php: ^8.0
* guzzlehttp/guzzle: ^7
* symbiote/silverstripe-queuedjobs: ^4
* elastic/enterprise-search: ^8.3
* silverstripe/versioned: ^1

## Documentation

Expand Down
8 changes: 0 additions & 8 deletions _config/dataobject.yml

This file was deleted.

2 changes: 1 addition & 1 deletion _config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ Name: search-service-default
---
SilverStripe\Core\Injector\Injector:
SilverStripe\SearchService\Interfaces\IndexingInterface:
class: SilverStripe\SearchService\Services\Naive\NaiveSearchService
class: SilverStripe\SearchService\Service\Naive\NaiveSearchService
19 changes: 10 additions & 9 deletions _config/appsearch.yml → _config/enterprisesearch.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
---
Name: silverstripe-search-service-appsearch
Name: silverstripe-search-service-enterprisesearch
Only:
envvarset: 'APP_SEARCH_API_KEY'
envvarset: 'ENTERPRISE_SEARCH_API_KEY'
After:
- 'silverstripe-search-service-dataobject'
- 'search-service-default'
---
SilverStripe\Core\Injector\Injector:
SilverStripe\SearchService\Interfaces\IndexingInterface:
class: SilverStripe\SearchService\Services\AppSearch\AppSearchService
class: SilverStripe\SearchService\Service\EnterpriseSearch\EnterpriseSearchService
constructor:
client: '%$Elastic\AppSearch\Client\Client'
client: '%$Elastic\EnterpriseSearch\Client'
configuration: '%$SilverStripe\SearchService\Service\IndexConfiguration'
builder: '%$SilverStripe\SearchService\Service\DocumentBuilder'
Elastic\AppSearch\Client\Client:
factory: SilverStripe\SearchService\Services\AppSearch\ClientFactory
Elastic\EnterpriseSearch\Client:
factory: SilverStripe\SearchService\Service\EnterpriseSearch\ClientFactory
constructor:
endpoint: '`APP_SEARCH_ENDPOINT`'
apiKey: '`APP_SEARCH_API_KEY`'
host: '`ENTERPRISE_SEARCH_ENDPOINT`'
token: '`ENTERPRISE_SEARCH_API_KEY`'
http_client: '%$GuzzleHttp\Client'
SilverStripe\SearchService\Service\IndexConfiguration:
id_field: 'id'
source_class_field: 'source_class'

## customise the dataobject fields for AppSearch compatability
## customise the dataobject fields for EnterpriseSearch compatability
SilverStripe\SearchService\DataObject\DataObjectDocument:
id_field: record_id
base_class_field: record_base_class
Expand Down
24 changes: 13 additions & 11 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "silverstripe/silverstripe-search-service",
"description": "Elastic App Search Functionality",
"description": "Abstract Search Service with Elastic Enterprise Search Functionality",
"type": "silverstripe-vendormodule",
"license": "BSD-3-Clause",
"authors": [
Expand All @@ -14,19 +14,15 @@
}
],
"require": {
"php": "^7.4 || ^8.0",
"symbiote/silverstripe-queuedjobs": "^4.0.0",
"silverstripe-terraformers/app-search-php-8": "^7.14.0",
"php": "^8.0",
"guzzlehttp/guzzle": "^7",
"symbiote/silverstripe-queuedjobs": "^4",
"elastic/enterprise-search": "^8.3",
"silverstripe/versioned": "^1"
},
"require-dev": {
"phpunit/phpunit": "^9.5",
"squizlabs/php_codesniffer": "^3"
},
"scripts": {
"lint": "phpcs --extensions=php src/ tests/",
"syntax-check": "find src/ tests/ -type f -name '*.php' -exec php -l {} \\;",
"lint-clean": "phpcbf src/ tests/"
"slevomat/coding-standard": "^8.3.0"
},
"autoload": {
"psr-4": {
Expand All @@ -35,5 +31,11 @@
}
},
"prefer-stable": true,
"minimum-stability": "dev"
"minimum-stability": "dev",
"config": {
"allow-plugins": {
"composer/installers": true,
"dealerdirect/phpcodesniffer-composer-installer": true
}
}
}
104 changes: 104 additions & 0 deletions docs/en/changes-in-v2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Changes in Version 2

## Preamble

If your existing implementation of this module simply uses the out of the box extensions, jobs, and tasks, without
any customisations, then it's very likely that the changes to Environment Variable names would be the only change
required for you.

## Breaking changes

### PHP

Minimum PHP requirement has been increased to PHP 8.

### Environment variables

Usages of the name `APP` has been replaced with `ENTERPRISE`.

Before:
```yml
APP_SEARCH_ENGINE_PREFIX=""
APP_SEARCH_API_KEY=""
APP_SEARCH_API_SEARCH_KEY=""
APP_SEARCH_ENDPOINT=""
```

After:
```yml
ENTERPRISE_SEARCH_ENGINE_PREFIX=""
ENTERPRISE_SEARCH_API_KEY=""
ENTERPRISE_SEARCH_API_SEARCH_KEY=""
ENTERPRISE_SEARCH_ENDPOINT=""
```

### Method return types

Some methods previously returned `void` or `$this`, which meant they didn't give any useful feedback from the request
we had just made.

Methods like `EnterpriseSearchService::configure()` now return info about the response (in this case, an array of the
active configuration for each index).

Methods with changed return types:

* `IndexingInterface::configure()`
* `IndexingInterface::addDocument()`
* `IndexingInterface::removeDocument()`
* `BatchDocumentInterface::addDocuments()`
* `BatchDocumentInterface::removeDocuments()`

### Pretty much every property/parameter everywhere

I think we've been able to keep the general API for all methods (that being, the order and purpose of params) the same,
but a lot of methods have had type declarations added, so if you are extended these classes and overriding methods,
then these would likely be breaking changes for you.

Where possible, properties have been given type hints (where they didn't previously). Exceptions are the usual
properties that extend some other vendor classes that they have to match.

### `NaiveSearchService`

Practically, I don't think anyone would have been accessing this class, but the namespace has changed to be consistent
with other classes.

Before: `SilverStripe\SearchService\Services\Naive\NaiveSearchService`
After: `SilverStripe\SearchService\Service\Naive\NaiveSearchService`

## Maybe breaking

### Default HTTP Client

We **don't think** this will be a breaking change, as the old App Search already explicitly used `Guzzle` as its HTTP
Client. However, the new Enterprise search uses PSR-18 "discovery". We found this to be a bit too fragile (EG: It was
breaking with Symfony Client), so we've added a new config to the `ClientFactory` to allow folks to specify what client
they would like instantiated. Default is `Guzzle`.

```yml
SilverStripe\Core\Injector\Injector:
Elastic\EnterpriseSearch\Client:
factory: SilverStripe\SearchService\Service\EnterpriseSearch\ClientFactory
constructor:
# original configs
host: '`ENTERPRISE_SEARCH_ENDPOINT`'
token: '`ENTERPRISE_SEARCH_API_KEY`'
# new config
http_client: '%$GuzzleHttp\Client'
```
The Elastic Enterprise dependency seems to be tested on Guzzle specifically though, so any change here would need to be
covered by your own testing.
### `recordBaseClass` and `pageContent`

There were two conflicting configs, one defined these fields in snake case (EG: `record_base_class`), and the other
defined them in camel case (EG: `recordBaseClass`). I've standardised all configs to snake case.

Looking through some of my own projects, we seem to use the snake case, so this might not be a breaking change.

## New features

### New Permission for triggering ReIndex through Service Admin

`SearchAdmin_ReIndex` permission has been added so that it's not longer only ADMIN who are able to trigger a full
ReIndex through the Model Admin area.
8 changes: 4 additions & 4 deletions docs/en/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ SilverStripe\SearchService\Service\IndexConfiguration:
Let's look at each relevant node:
* `myindex`: The name of the index. The rules on what this can be named will vary depending
on your service provider. For AppSearch, it should only contain lowercase letters, numbers,
on your service provider. For EnterpriseSearch, it should only contain lowercase letters, numbers,
and hyphens.

* `includedClasses`: A list of content classes to index. These are just the _source_ of the
Expand All @@ -46,7 +46,7 @@ so when it finds that the property `$content` doesn't exist on the `SiteTree` in
will use a case matching strategy as a fallback.

It is important to note that the keys of `fields` can be named anything you like, so long
as it is valid in your search service provider (for AppSearch, that's all lowercase and
as it is valid in your search service provider (for EnterpriseSearch, that's all lowercase and
underscores). There is no reason why `title` cannot be `document_title` for instance,
in the above configuration, as we've explicitly mapped the field to `Title`.

Expand Down Expand Up @@ -96,7 +96,7 @@ This will roughly get indexed as a structure like this:
}
```

For more information on AppSearch specific configuration, see the [Implementations](implementations.md#appsearch)
For more information on EnterpriseSearch specific configuration, see the [Implementations](implementations.md#EnterpriseSearch)
document.

## Advanced configuration
Expand All @@ -122,7 +122,7 @@ Let's look at all the settings on the `IndexConfiguration` class:
<tr>
<td>batch_size</td>
<td>int</td>
<td>The default size of a batch of documents (e.g. when bulk indexing) AppSearch
<td>The default size of a batch of documents (e.g. when bulk indexing) EnterpriseSearch
limit is `100`</td>
<td>100</td>
</tr>
Expand Down
2 changes: 1 addition & 1 deletion docs/en/customising.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

The goal of this module is to provide a set of useful abstraction layers upon which developers
can build search-as-a-service integrations that best suit their needs. Out of the box, it
includes concretions for Elastic AppSearch and DataObject content, but this can be extended.
includes concretions for Elastic EnterpriseSearch and DataObject content, but this can be extended.
This section of the document covers the customisation and extension of those abstraction
layers.

Expand Down
Loading

0 comments on commit b1ed1e9

Please sign in to comment.