Auswertung von MongoDB-ähnlichen JSON-Abfragen in PHP

Betrachten Sie die folgende (ziemlich komplizierte) Abfrage, die in diesem JSON-Objekt ausgedrückt wird:

{
    "name": "Kindle Fire",
    "sale": true,
    "price": {
        "$gt": 199,
        "$lt": 264
    },
    "price.vat": { // bogus, just to show $a['price.vat'] == $a['price']['vat']
        "$lte": 1.2
    },
    "$or": {
        "qty": {
            "$gt": 30
        },
        "eta": {
            "$or": {
                "$lt": 3,
                "$gt": 30
            }
        }
    },
    "countriesAvailable": {
        "$in": [
            "US",
            "CA"
        ]
    }
}
Zielsetzung

Ich möchte diesen JSON analysieren, damit er das PHP - Äquivalent von (where$a sind meine Zieldaten):

$a['name'] == 'Kindle Fire' &&
$a['sale'] == true &&
(
    $a['price'] > 199 && $a['price'] < 264
) &&
$a['price']['vat'] <= 1.2 &&
(
    $a['qty'] > 30 ||
    (
        $a['eta'] < 3 || $a['eta'] > 30
    )
) &&
in_array($a['countriesAvailable'], array('US', 'CA'))

Ich habe wenig Erfahrung damit, Ausdrucksauswerter zu erstellen. Meine Idee ist es, die Abfrage von der innersten zur äußersten Ebene zu durchlaufen und die entsprechende aufzurufenMongoDB-Operator Methoden nach Bedarf.

Vorausgesetzt$a Entspricht die Abfrage, wäre dies der Bewertungsplan:

$query = array();
$query['name'] = true;
$query['sale'] = true;
$query['price'] = array();
$query['price']['$gt'] = true;
$query['price']['$lt'] = true;
$query['price']['vat'] = array();
$query['price']['vat']['$lte'] = true;
$query['$or'] = array();
$query['$or']['qty'] = array();
$query['$or']['qty']['$gt'] = false;
$query['$or']['eta'] = array();
$query['$or']['eta']['$or'] = array();
$query['$or']['eta']['$or']['$lt'] = true;
$query['$or']['eta']['$or']['$gt'] = false;
$query['countriesAvailable'] = array();
$query['countriesAvailable']['$in'] = true;

Der zweite Schritt:

$query = array();
$query['name'] = true;
$query['sale'] = true;
$query['price'] = array();
$query['price']['$gt'] = true;
$query['price']['$lt'] = true;
$query['price']['vat'] = true;
$query['$or'] = array();
$query['$or']['qty'] false;
$query['$or']['eta'] = array();
$query['$or']['eta']['$or'] true;
$query['countriesAvailable'] = true;

Der dritte Schritt:

$query = array();
$query['name'] = true;
$query['sale'] = true;
$query['price'] = true;
$query['$or'] = array();
$query['$or']['qty'] false;
$query['$or']['eta'] true;
$query['countriesAvailable'] = true;

Der vierte Schritt:

$query = array();
$query['name'] = true;
$query['sale'] = true;
$query['price'] = true;
$query['$or'] = true;
$query['countriesAvailable'] = true;

Da alle Werte Boolesche Werte sind, endet die Auswertung mit der Rückgabe!in_array(false, $query, true).

Wenn es einen besseren Ansatz gibt, lassen Sie es mich wissen.

Problem: Zugriff auf übergeordnete Array-Schlüssel

Ich stecke fest und versuche, die innersten Elemente und den relevanten Array-Index (ignorierende Operatoren) zu erhaltenPfadZum Beispiel, wenn ich a verwendeRecursiveIteratorIterator Ich erhalte die korrekten Werte für die erste Iteration:

$nodes = new ArrayIterator($query);
$iterator = new RecursiveArrayIterator($nodes);
$iteratorIterator = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::LEAVES_ONLY);

print_r(iterator_to_array($iteratorIterator));

Array
(
    [name] => Kindle Fire HD
    [sale] => 1
    [$gt] => 30
    [$lt] => 3
    [$lte] => 1.2
    [0] => US
    [1] => CA
)

Es nützt jedoch wenig, da ich mir nicht sicher bin, was$a Index, auf den sich die Schlüssel beziehen, ganz zu schweigen davon, dass die Schlüsselwerte durch letztere Einträge überschrieben werden und dass ich ihre Werte nicht ändern kann.

Ich habe auch versucht, mit zu spielenRecursiveArrayIterator, aber ohne diehasParent() / getParent() Methoden scheint es mir nicht viel Vorteil zu geben, nur das Array zu belehren.

Irgendwelche Vorschläge?

Antworten auf die Frage(1)

Ihre Antwort auf die Frage