この JSON オブジェクトで表現された次の (かなり複雑な) クエリを検討してください。
{
"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"
]
}
}
目的
$a
その JSON を解析して、(where is my target data)に相当する PHP に評価されるようにします。
$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'))
式評価器を構築した経験はほとんどありません。私の考えは、クエリを最も内側のレベルから最も外側のレベルまでトラバースし、必要に応じて対応するMongoDB オペレーターメソッドを呼び出すことです。
クエリに一致すると仮定すると$a
、これは評価計画になります。
$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;
2 番目のステップ:
$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;
3 番目のステップ:
$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;
4 番目のステップ:
$query = array();
$query['name'] = true;
$query['sale'] = true;
$query['price'] = true;
$query['$or'] = true;
$query['countriesAvailable'] = true;
すべての値がブール値であるため、評価は を返し!in_array(false, $query, true)
ます。
より良いアプローチが存在する場合は、お知らせください。
問題: 親配列キーへのアクセス
最も内側の要素と関連する (演算子を無視する) 配列 index pathを取得しようとして立ち往生しています。たとえば、RecursiveIteratorIterator
最初の反復で正しい値を取得する場合:
$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
)
$a
ただし、キーの値が後のエントリによって上書きされていることや、それらの値を変更できないという事実は言うまでもなく、キーが参照しているインデックスがわからないため、ほとんど役に立ちません。
私も で遊んでみましRecursiveArrayIterator
たが、hasParent()
/getParent()
メソッドがなければ、単に配列を foreach するよりもあまり利点がないようです。
助言がありますか?