# Eigene SQL-Sortierung in Product Repository

**URL:** <https://forum.shopware.com/t/eigene-sql-sortierung-in-product-repository/90106>\
**Category:** Programmierung\
**Created:** [3. September 2021 um 07:50 UTC](https://forum.shopware.com/t/eigene-sql-sortierung-in-product-repository/90106 "2021-09-03T07:50:16Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![ansgar](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.shopware.com/ansgar/32/7871_2.png) [@ansgar](https://forum.shopware.com/u/ansgar)\
**Post date:** [3. September 2021 um 07:50 UTC](https://forum.shopware.com/t/eigene-sql-sortierung-in-product-repository/90106/1 "2021-09-03T07:50:16Z")

</div>

Ich möchte in einem Plugin eine hartkodierte Liste an Produkt-Nummern zur Sortierung einer Produktliste übergeben. Normalerweise würde man einem `Criteria` ein `FieldSorting` übergeben. Das funktioniert aber soweit ich weiß nur mit definierten Feldnamen, wie zB „productNumber“. Ich würde da gern etwas SQL Code übergeben (`CASE ... END`), was aber so nicht funktioniert:

```auto
$hardCodesProductNumbers = ['123','ABC'];
$criteria = (new Criteria())
	->addFilter(new EqualsFilter('active', '1'))
	->addFilter(new EqualsAnyFilter('productNumber', $hardCodesProductNumbers));
$criteria->addSorting(new FieldSorting('CASE productNumber WHEN "123" THEN 1 WHEN "ABC" THEN 2 ELSE 3 END', FieldSorting::ASCENDING));
$products = $this->productRepository->search($criteria, $context);

```

Hier steht wohl beschrieben wie man eine eigene Sortierung erzeugt:

> **[Add custom sorting for product listing](https://developer.shopware.com/docs/guides/plugins/plugins/storefront/add-custom-sorting-product-listing)**

Aber so eine Sortierung würde dem Benutzer auch per Dropdown angeboten, was ich gar nicht will. Stattdessen will ich die Sortierung nur einmal intern verwenden. Meine hartkodierte Liste ändert sich häufiger, daher sollte die Sortierung auch nicht gespeichert werden.

---

<div class="post-metadata">

**Author:** ![AlexGalax](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.shopware.com/alexgalax/32/9925_2.png) [@AlexGalax](https://forum.shopware.com/u/AlexGalax)\
**Post date:** [3. September 2021 um 13:16 UTC](https://forum.shopware.com/t/eigene-sql-sortierung-in-product-repository/90106/2 "2021-09-03T13:16:29Z")

</div>

Es gibt nur einen Sortierungs-Typ in `core/Framework/DataAbstractionLayer/Search/Sorting`. Dieser Sortiert nur nach einzelnen Feldern.

Ich würde an deiner Stelle ein numerisches custom field in der products entity anlegen. Dieses füllst du dann mit Werten entsprechend der Priorität und kannst es dann mit dem einfachen `FieldSorting` sortieren. Ist was die Performance angeht auf jeden Fall besser.

---

<div class="post-metadata">

**Author:** ![ansgar](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.shopware.com/ansgar/32/7871_2.png) [@ansgar](https://forum.shopware.com/u/ansgar)\
**Post date:** [6. September 2021 um 08:36 UTC](https://forum.shopware.com/t/eigene-sql-sortierung-in-product-repository/90106/3 "2021-09-06T08:36:50Z")

</div>

Diese hartkodierte Liste ändert sich häufig. Das würde bedeuten dass ich die Werte erst zur Laufzeit in ein Custom Field schreiben muss, um danach zu sortieren.

Kann ich ansonsten das Ergebnis (also ein `EntitySearchResult`) im Nachhinein noch sortieren? Habe mal versucht auf ein array zu casten und dann per `usort()`… aber als Array lässt sich das nicht mehr in Twig’s verwenden.

---

<div class="post-metadata">

**Author:** ![AlexGalax](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.shopware.com/alexgalax/32/9925_2.png) [@AlexGalax](https://forum.shopware.com/u/AlexGalax)\
**Post date:** [6. September 2021 um 09:33 UTC](https://forum.shopware.com/t/eigene-sql-sortierung-in-product-repository/90106/4 "2021-09-06T09:33:16Z")

</div>

Wenn die Liste nicht besonders groß ist, kannst die die auch loopen und einzelnd nacheinander suchen, dann wären sie wie die Ausgangsliste sortiert.

Außerdem ist `EntitySearchResult.elements` doch ein Array was man sortieren kann?

Oder du kannst das ScoreQuery benutzen um den Ergebnissen einen Score zu geben. Aber da weiß ich nicht ob das gut performt oder wie genau das ist. In diesem Beispiel hat es funktioniert:

```php

        $hardCodesProductNumbers = ['511090138','511280129','511480038'];
        $criteria = (new Criteria())
            ->addFilter(new EqualsFilter('active', '1'))
            ->addFilter(new EqualsAnyFilter('productNumber', $hardCodesProductNumbers));

        $criteria->addQuery(
            new ScoreQuery(new ContainsFilter('productNumber', '511480038'), 3000)
        );
        $criteria->addQuery(
            new ScoreQuery(new ContainsFilter('productNumber', '511280129'), 2000)
        );
        $criteria->addQuery(
            new ScoreQuery(new ContainsFilter('productNumber', '511090138'), 1000)
        );

        $products = $this->productRepository->search($criteria, $context);

```

---

<div class="post-metadata">

**Author:** ![ansgar](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.shopware.com/ansgar/32/7871_2.png) [@ansgar](https://forum.shopware.com/u/ansgar)\
**Post date:** [6. September 2021 um 10:30 UTC](https://forum.shopware.com/t/eigene-sql-sortierung-in-product-repository/90106/5 "2021-09-06T10:30:26Z")

</div>

Der `ScoreQuery` scheint bei mir auch zu funktionieren, und ist mit wenig Aufwand generiert. Die Performance ist bei mir nicht messbar unterschiedlich zur Abfrage ohne ScoreQuery.

Werde das mal beobachten, sieht aber schon mal nach einer guten Lösung aus. Vielen Dank!

---

<div class="post-metadata">

**Author:** ![ansgar](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.shopware.com/ansgar/32/7871_2.png) [@ansgar](https://forum.shopware.com/u/ansgar)\
**Post date:** [6. September 2021 um 11:11 UTC](https://forum.shopware.com/t/eigene-sql-sortierung-in-product-repository/90106/6 "2021-09-06T11:11:14Z")

</div>

Also Array-Sortierung war eigentlich auch ne gute Idee, denn `EntitySearchResult` hat u.a. eine `sort()` Methode der man ein Closure übergeben kann:

```auto
$hardCodesProductNumbers = ['123','ABC'];
$criteria = (new Criteria())
	->addFilter(new EqualsFilter('active', '1'))
	->addFilter(new EqualsAnyFilter('productNumber', $hardCodesProductNumbers));
$products = $this->productRepository->search($criteria, $context);
$sortClosure = function($a, $b) use($hardCodesProductNumbers): int {
	$idxA = array_search($a->productNumber, $hardCodesProductNumbers);
	$idxB = array_search($b->productNumber, $hardCodesProductNumbers);
	if($idxA == $idxB) {
		return 0;
	}
	else {
		return ($idxA < $idxB) ? -1 : 1;
	}
};
$products->sort($sortClosure);

```

---

<div class="post-metadata">

**Author:** ![AlexGalax](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.shopware.com/alexgalax/32/9925_2.png) [@AlexGalax](https://forum.shopware.com/u/AlexGalax)\
**Post date:** [7. September 2021 um 06:15 UTC](https://forum.shopware.com/t/eigene-sql-sortierung-in-product-repository/90106/7 "2021-09-07T06:15:10Z")

</div>

> [@ansgar](#):
>
> `EntitySearchResult` hat u.a. eine `sort()` Methode

nice, gut zu wissen!
