Skip to content

Commit 38371ab

Browse files
authored
Attempt to make term <> collection query more performant (#345)
1 parent 4d41965 commit 38371ab

File tree

1 file changed

+23
-36
lines changed

1 file changed

+23
-36
lines changed

src/Taxonomies/TermQueryBuilder.php

Lines changed: 23 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace Statamic\Eloquent\Taxonomies;
44

5-
use Illuminate\Support\Arr;
65
use Illuminate\Support\Str;
76
use Statamic\Contracts\Taxonomies\Term as TermContract;
87
use Statamic\Facades\Blink;
@@ -215,46 +214,34 @@ private function applyCollectionAndTaxonomyWheres()
215214
? Taxonomy::handles()->all()
216215
: $this->taxonomies;
217216

218-
// get entries in each collection that have a value for the taxonomies we are querying
219-
// or the ones associated with the collection
220-
// what we ultimately want is a subquery for terms in the form:
221-
// where('taxonomy', $taxonomy)->whereIn('slug', $slugArray)
222-
$collectionTaxonomyHash = md5(collect($this->collections)->merge(collect($taxonomies))->sort()->join('-'));
223-
224-
Blink::once("eloquent-taxonomy-hash-{$collectionTaxonomyHash}", function () use ($taxonomies) {
225-
return Entry::query()
226-
->whereIn('collection', $this->collections)
227-
->select($taxonomies)
228-
->get();
229-
})
230-
->flatMap(function ($entry) use ($taxonomies) {
231-
$slugs = [];
232-
foreach ($entry->collection()->taxonomies()->map->handle() as $taxonomy) {
233-
if (in_array($taxonomy, $taxonomies)) {
234-
foreach (Arr::wrap($entry->get($taxonomy, [])) as $term) {
235-
$slugs[] = $taxonomy.'::'.$term;
236-
}
237-
}
217+
collect($taxonomies)->each(function ($taxonomy) use ($query) {
218+
$collectionTaxonomyHash = md5(collect($this->collections)->merge([$taxonomy])->sort()->join('-'));
219+
220+
$terms = Blink::once("eloquent-taxonomy-hash-{$collectionTaxonomyHash}", function () use ($taxonomy) {
221+
if (! $taxonomy = Taxonomy::find($taxonomy)) {
222+
return [];
238223
}
239224

240-
return $slugs;
241-
})
242-
->unique()
243-
->map(function ($term) {
244-
return [
245-
'taxonomy' => Str::before($term, '::'),
246-
'term' => Str::after($term, '::'),
247-
];
248-
})
249-
->mapToGroups(function ($item) {
250-
return [$item['taxonomy'] => $item['term']];
251-
})
252-
->each(function ($terms, $taxonomy) use ($query) {
225+
return TermModel::where('taxonomy', $taxonomy)
226+
->select('slug')
227+
->get()
228+
->map(function ($term) use ($taxonomy) {
229+
return Entry::query()
230+
->whereIn('collection', $this->collections)
231+
->whereJsonContains('data->'.$taxonomy, [$term->slug])
232+
->count() > 0 ? $term->slug : null;
233+
})
234+
->filter()
235+
->values();
236+
});
237+
238+
if ($terms->isNotEmpty()) {
253239
$query->orWhere(function ($query) use ($terms, $taxonomy) {
254240
$query->where('taxonomy', $taxonomy)
255-
->whereIn('slug', $terms);
241+
->whereIn('slug', $terms->all());
256242
});
257-
});
243+
}
244+
});
258245
});
259246
}
260247

0 commit comments

Comments
 (0)