|
11 | 11 | * source code. |
12 | 12 | */ |
13 | 13 |
|
| 14 | +use Neos\Flow\Annotations as Flow; |
14 | 15 | use Flowpack\ElasticSearch\ContentRepositoryAdaptor\Driver\QueryInterface; |
15 | 16 | use Flowpack\ElasticSearch\ContentRepositoryAdaptor\Dto\SearchResult; |
16 | 17 | use Flowpack\ElasticSearch\ContentRepositoryAdaptor\ElasticSearchClient; |
|
21 | 22 | use Neos\ContentRepository\Domain\Model\NodeInterface; |
22 | 23 | use Neos\ContentRepository\Search\Search\QueryBuilderInterface; |
23 | 24 | use Neos\Eel\ProtectedContextAwareInterface; |
24 | | -use Neos\Flow\Annotations as Flow; |
25 | 25 | use Neos\Flow\ObjectManagement\ObjectManagerInterface; |
26 | 26 | use Neos\Flow\Utility\Now; |
27 | 27 | use Neos\Utility\Arrays; |
@@ -567,6 +567,7 @@ public function fetch() |
567 | 567 | try { |
568 | 568 | $timeBefore = microtime(true); |
569 | 569 | $request = $this->request->getRequestAsJson(); |
| 570 | + |
570 | 571 | $response = $this->elasticSearchClient->getIndex()->request('GET', '/_search', [], $request); |
571 | 572 | $timeAfterwards = microtime(true); |
572 | 573 |
|
@@ -670,6 +671,48 @@ public function highlight($fragmentSize, $fragmentCount = null) |
670 | 671 | return $this; |
671 | 672 | } |
672 | 673 |
|
| 674 | + /** |
| 675 | + * This method is used to define a more like this query. |
| 676 | + * The More Like This Query (MLT Query) finds documents that are "like" a given set of documents. |
| 677 | + * See: https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-mlt-query.html |
| 678 | + * |
| 679 | + * @param array $like An array of strings or documents |
| 680 | + * @param array $fields Fields to compare other docs with |
| 681 | + * @param array $options Additional options for the more_like_this quey |
| 682 | + * @return ElasticSearchQueryBuilder |
| 683 | + */ |
| 684 | + public function moreLikeThis($like, array $fields = [], array $options = []) |
| 685 | + { |
| 686 | + $like = is_array($like) ? $like : [$like]; |
| 687 | + |
| 688 | + $getDocumentDefinitionByNode = function (QueryInterface $request, NodeInterface $node): array { |
| 689 | + $request->queryFilter('term', ['__identifier' => $node->getIdentifier()]); |
| 690 | + $response = $this->elasticSearchClient->getIndex()->request('GET', '/_search', [], $request->toArray())->getTreatedContent(); |
| 691 | + |
| 692 | + $respondedDocuments = Arrays::getValueByPath($response, 'hits.hits'); |
| 693 | + if (count($respondedDocuments) === 0) { |
| 694 | + throw new Exception(sprintf('The node with identifier %s was not found in the elasticsearch index', $node->getIdentifier()), 1536485615); |
| 695 | + } |
| 696 | + $respondedDocument = current($respondedDocuments); |
| 697 | + return [ |
| 698 | + '_id' => $respondedDocument['_id'], |
| 699 | + '_type' => $respondedDocument['_type'], |
| 700 | + '_index' => $respondedDocument['_index'], |
| 701 | + ]; |
| 702 | + }; |
| 703 | + |
| 704 | + foreach ($like as $key => $likeElement) { |
| 705 | + if ($likeElement instanceof NodeInterface) { |
| 706 | + $like[$key] = $getDocumentDefinitionByNode(clone $this->request, $likeElement); |
| 707 | + } |
| 708 | + } |
| 709 | + |
| 710 | + $this->request->moreLikeThis($like, $fields, $options); |
| 711 | + |
| 712 | + return $this; |
| 713 | + } |
| 714 | + |
| 715 | + |
673 | 716 | /** |
674 | 717 | * Sets the starting point for this query. Search result should only contain nodes that |
675 | 718 | * match the context of the given node and have it as parent node in their rootline. |
|
0 commit comments