Skip to content

Commit 34dbb10

Browse files
authored
Merge pull request #107 from ensi-platform/v8-pinned-2
V8 pinned fix
2 parents 5adb4a5 + b97a9a7 commit 34dbb10

File tree

6 files changed

+58
-16
lines changed

6 files changed

+58
-16
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,14 @@ $searchQuery->sumSortBy('field', 'asc');
130130
$searchQuery->medianSortBy('field', 'asc');
131131
```
132132

133+
### Pinned query
134+
135+
Promotes selected documents to rank higher than those matching a given query. This feature is typically used to guide searchers to curated documents that are promoted over and above any "organic" matches for a search. The promoted or "pinned" documents are identified using the document IDs stored in the _id field.
136+
137+
```php
138+
$searchQuery->pinned(['doc-3', 'doc-1', 'doc-2']);
139+
```
140+
133141
### Pagination
134142

135143
#### Offset Pagination

src/Concerns/DecoratesBoolQuery.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,4 +172,11 @@ public function addFunctionScore(array $functions, ?DSLAware $query = null, ?Fun
172172

173173
return $this;
174174
}
175+
176+
public function pinned(array $ids, ?DSLAware $query = null): static
177+
{
178+
$this->forwardCallTo($this->boolQuery(), __FUNCTION__, func_get_args());
179+
180+
return $this;
181+
}
175182
}

src/Contracts/BoolQuery.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,6 @@ public function whereBetween(string $field, mixed $from, mixed $to): static;
5353
* @param ?FunctionScoreOptions $options
5454
*/
5555
public function addFunctionScore(array $functions, ?DSLAware $query = null, ?FunctionScoreOptions $options = null): static;
56+
57+
public function pinned(array $ids, ?DSLAware $query = null): static;
5658
}

src/Filtering/BoolQueryBuilder.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Ensi\LaravelElasticQuery\Filtering\Criterias\MultiMatch;
2222
use Ensi\LaravelElasticQuery\Filtering\Criterias\Nested;
2323
use Ensi\LaravelElasticQuery\Filtering\Criterias\OneMatch;
24+
use Ensi\LaravelElasticQuery\Filtering\Criterias\Pinned;
2425
use Ensi\LaravelElasticQuery\Filtering\Criterias\RangeBound;
2526
use Ensi\LaravelElasticQuery\Filtering\Criterias\Term;
2627
use Ensi\LaravelElasticQuery\Filtering\Criterias\Terms;
@@ -279,6 +280,13 @@ public function addFunctionScore(array $functions, ?DSLAware $query = null, ?Fun
279280
return $this;
280281
}
281282

283+
public function pinned(array $ids, ?DSLAware $query = null): static
284+
{
285+
$this->must->add(new Pinned($ids, $query));
286+
287+
return $this;
288+
}
289+
282290
public function addMustBool(callable $fn): static
283291
{
284292
$this->must->add(static::make(builder: $fn));

src/Filtering/Criterias/Pinned.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace Ensi\LaravelElasticQuery\Filtering\Criterias;
4+
5+
use Ensi\LaravelElasticQuery\Contracts\Criteria;
6+
use Ensi\LaravelElasticQuery\Contracts\DSLAware;
7+
use stdClass;
8+
use Webmozart\Assert\Assert;
9+
10+
class Pinned implements Criteria
11+
{
12+
public function __construct(
13+
private array $ids,
14+
private ?DSLAware $query = null,
15+
) {
16+
Assert::minCount($ids, 1);
17+
}
18+
19+
public function toDSL(): array
20+
{
21+
$body = [
22+
'ids' => $this->ids,
23+
'organic' => ['match_all' => new stdClass()],
24+
];
25+
26+
if ($this->query) {
27+
$body['organic'] = $this->query->toDSL();
28+
}
29+
30+
return ['pinned' => $body];
31+
}
32+
}

src/Search/SearchQuery.php

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ class SearchQuery implements SortableQuery, CollapsibleQuery, HighlightingQuery
4040
protected ?int $from = null;
4141
protected array $fields = [];
4242
protected array $include = [];
43-
protected ?array $pinnedIds = null;
4443
protected array $exclude = [];
4544
protected ?string $searchType = null;
4645

@@ -150,19 +149,12 @@ protected function execute(
150149
$dsl = [
151150
'size' => $size,
152151
'from' => $from,
153-
'query' => [],
152+
'query' => $this->boolQuery->toDSL(),
154153
'track_total_hits' => $totals,
155154
'_source' => $this->sourceToDSL($source),
156155
'fields' => $source && $this->fields ? $this->fields : null,
157156
];
158157

159-
if ($this->pinnedIds) {
160-
$dsl['query']['pinned']['ids'] = $this->pinnedIds;
161-
$dsl['query']['pinned']['organic'] = $this->boolQuery->toDSL();
162-
} else {
163-
$dsl['query'] = $this->boolQuery->toDSL();
164-
}
165-
166158
$sorts ??= $this->sorts;
167159
if (!$sorts->isEmpty()) {
168160
$dsl['sort'] = $sorts->toDSL();
@@ -253,13 +245,6 @@ public function setPostFilter(BoolQueryBuilder $boolQueryBuilder): static
253245
return $this;
254246
}
255247

256-
public function pinned(array $ids): static
257-
{
258-
$this->pinnedIds = $ids;
259-
260-
return $this;
261-
}
262-
263248
public function addAggregations(Aggregation $aggregation): static
264249
{
265250
$this->aggregations ??= new AggregationCollection();

0 commit comments

Comments
 (0)