Skip to content

Commit

Permalink
chore (doc) : update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Hilsonxhero committed Feb 7, 2023
1 parent d1ac3bd commit a986c80
Show file tree
Hide file tree
Showing 19 changed files with 977 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
theme: jekyll-theme-cayman
42 changes: 42 additions & 0 deletions docs/advanced-queries.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Advanced queries
Explorer expands your possibilities using query builders to write more complex queries.
First there are the three methods to set the context of the query: must, should and filter.

From the Elasticsearch [documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html):

**must**: The query must appear in matching documents and will contribute to the score.

**should**: The query should appear in the matching document.

**filter**: The query must appear in matching documents. However unlike must the score of the query will be ignored.

Together they take in Explorer a _more-matches-is-better_ approach, the more a document matches with the given queries, the higher its score.
The filter context is best used for structured data, such as dates or flags.

In Explorer, you can build a compound query as complex as you like. Elasticsearch provides a broad set of queries,
these are the query types implementing `SyntaxInterface`. There is for example the `MultiMatch` for fuzzy search and Term for a very precise search.
It is too much to list every type of query here. At the time of writing, Explorer does not yet have every Elasticsearch query type that is out there.
It is however very easy to write a class for a missing query type, and if you do write one a Pull Request is more than welcome!

## Fuzziness
The Matching and MultiMatch queries accept a fuzziness parameter.
By default, it is set to 'auto' but the [Elasticsearch docs](https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#fuzziness) explain in depth which other values you could use.

> "When querying text or keyword fields, fuzziness is interpreted as a Levenshtein Edit Distance - the number of one character changes that need to be made to one string to make it the same as another string."
## Retrieving selected fields
By default Explorer will retrieve all fields for the documents that get returned.
You can change this by using the `field()` function on the search query builder.
It is important to know that this does necessarily have a performance improvement, the whole document is still being processed by Elasticsearch.

> "By default, each hit in the search response includes the document _source, which is the entire JSON object that was provided when indexing the document. To retrieve specific fields in the search response, you can use the fields parameter"
([source](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-fields.html))

```php
use App\Models\Post;

$results = Post::search('Self-steering')
->field('id')
->field('published_at')
->get();
```
17 changes: 17 additions & 0 deletions docs/aggregations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Aggregations
Aggregations are part of your search query and can summarise your data.
You can read more about aggregations in Elasticsearch in the [official documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html).
At this moment not all aggregation types are build in, but creating the missing ones should be doable (and these additions to the package are very welcome).

Adding aggregations makes your search query more advanced.
Here is an example from the demo application:

```php
$search = Cartographer::search();
$search->aggregation('places', new TermsAggregation('place'));

$results = $search->raw();
$aggregations = $results->aggregations();
```

This will return an array of metrics on how many times every place is present in the Elasticsearch index.
23 changes: 23 additions & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Console commands

## Create
```
php artisan elastic:create
```
Creates all indices.
Throws an exception if one already exists.

If you want to recreate an index, first make sure it's deleted and then create it.
Follow up with a scout import to refill the index as well.

## Delete
```
php artisan elastic:delete
```
Deletes all indices.

## Search
```
php artisan elastic:search <model> <term> --fields=<fields>
```
Rudimentary command to test a basic search query.
145 changes: 145 additions & 0 deletions docs/connection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# Connection

Explorer connects to ElasticSearch through the PHP ElasticSearch client and has several options to configure a connection.
The connection configuration is defined `config/explorer.php`.

## Basic

The most basic connection is with http without authorization.
```php
return [
'connection' => [
'host' => 'localhost',
'port' => '9200',
'scheme' => 'http',
],
];
```

## Elastic Cloud ID

Another connection option is to use an elastic cloud id as shown below
```php
return [
'connection' => [
'elasticCloudId' => 'staging:dXMtZWFzdC0xLmF3cy5mb3VuZC5pbyRjZWM2ZjI2MWE3NGJmMjRjZTMzYmI4ODExYjg0Mjk0ZiRjNmMyY2E2ZDA0MjI0OWFmMGNjN2Q3YTllOTYyNTc0Mw',
],
];
```

## Basic Authorization

To specify a username and password use the `auth` key with a `username` and a `password`.

```php
return [
'connection' => [
'host' => 'localhost',
'port' => '9200',
'scheme' => 'http',
'auth' => [
'username' => 'myName',
'password' => 'myPassword'
],
],
];
```

## API key

Replace the auth part with API and give it your key and id.

```php
return [
'connection' => [
'host' => 'localhost',
'port' => '9200',
'scheme' => 'http',
'api' => [
'id' => 'myId',
'key' => 'myKey'
],
],
];
```

## Verify TLS with CA

From Elastic 8 and upwards TLS is becoming the default, even in development. This means you will need to verify the CA. You can set the `ssl.verify` config key to the path of the CA, or to `false` to disable verification altogether.

> **Warning**
> Disabling CA verification on production is not recommended.
```php
return [
'connection' => [
'host' => 'localhost',
'port' => '9200',
'scheme' => 'http',
'ssl' => [
'verify' => './path/to/ca.crt',
],
],
];
```

To disable TLS verification set it to `false`. **NOT recommended for production**.
```php
return [
'connection' => [
'host' => 'localhost',
'port' => '9200',
'scheme' => 'http',
'ssl' => [
'verify' => false,
],
],
];
```

## TLS connection with a public certificate and private key
```
return [
'connection' => [
'host' => 'localhost',
'port' => '9200',
'scheme' => 'https',
'ssl' => [
'cert' => ['path/to/cert.pem', 'passphrase'],
'key' => ['path/to/key.pem', 'passphrase'],
],
],
];
```

## Multiple connections

Elastic can also have multiple possible connections

```php
use Elasticsearch\ConnectionPool\Selectors\RoundRobinSelector;

return [
'connection' => [
'host' => 'localhost',
'port' => '9200',
'scheme' => 'http',
'ssl' => [
'verify' => false,
],
'selector' => RoundRobinSelector::class
],
'additionalConnections' => [
[
'host' => 'localhost',
'port' => '9201',
'scheme' => 'http',
],
[
'host' => 'localhost',
'port' => '9202',
'scheme' => 'http',
]
],
];
```
34 changes: 34 additions & 0 deletions docs/debugging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#Debugging
Sometimes you might wonder why certain results are or aren't returned.

Here is an example from the Explorer demo app, although not with a complex query:

```php
class SearchController
{
public function __invoke(SearchFormRequest $request)
{
$people = Cartographer::search($request->get('keywords'))->get();

return view('search', [
'people' => $people,
]);
}
}
```

To debug this search query you can call the static `debug` method on the Elastic Engine for Laravel Scout:

```php
use Hilsonxhero\ElasticVision\Infrastructure\Scout\ElasticEngine;

$debug = ElasticEngine::debug();
```

The debug class that this method returns can give you the last executed query as an array or as json.
You should be able to copy-paste the json as a direct query to Elasticsearch.

```php
$lastQueryAsArray = ElasticEngine::debug()->array();
$lastQueryAsJson = ElasticEngine::debug()->json();
```
58 changes: 58 additions & 0 deletions docs/index-aliases.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Index aliases

Aliases allow you to use an index under a different name.This very useful for zero downtime deployments.

There are three aliases created: a read alias, a write alias and a history alias.
The read alias is used for reading, the write index is used for writing.
The history aggregates all old indices, which can be pruned.
When updating an index it is recreated to a new index with a unique name.
The "write" alias is pointed to the new index and all Scout updates will be forwarded to the "write" index.
After all entities are imported the "read" alias will also be pointed to the new index.

If you wish to keep the old indices set `prune_old_aliases` to false in `config/explorer.php`

## Using aliases

A model is only using index aliases if it implements the Aliased interface or enabled in the configuration (see [mapping](mapping.md)).

After that, any time you use the `scout:import` command a new index will be created and when the insertion of models is done the alias will be pointed to the new index.

```php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Hilsonxhero\ElasticVision\Application\Explored;
use Hilsonxhero\ElasticVision\Application\Aliased;
use Laravel\Scout\Searchable;

class Post extends Model implements Explored, Aliased
{
use HasFactory;
use Searchable;

//...
}
```

```php
return [
'indexes' => [
'posts' => [
'aliased' => true,
'properties' => [
'id' => 'keyword',
'title' => 'text',
'created_at' => 'date',
'published' => 'boolean',
'author' => 'nested',
],
],
],
];
```

Be aware that if you currently already have indices and would like to move to using aliases you will need to delete those indices before configuring the aliases.
In Elasticsearch a given name can only be either an index or alias, not both and this cannot be changed on-the-fly.
Loading

0 comments on commit a986c80

Please sign in to comment.