MongoDB
 sql >> डेटाबेस >  >> NoSQL >> MongoDB

GoMongoDB जैसी क्वेरी एक्सप्रेशन ऑब्जेक्ट मूल्यांकन को लागू करना

परिचय

मुझे लगता है कि PHP में MongoDB जैसी JSON क्वेरी का मूल्यांकन करने से आपको आवश्यक सभी जानकारी मिल गई है। आपको बस समाधान के साथ रचनात्मक होना है और आप जो चाहते हैं उसे हासिल करना है

सरणी

आइए मान लें कि हमारे पास निम्नलिखित json है सरणी में कनवर्ट किया गया

$json = '[{
    "name":"Mongo",
    "type":"db",
    "release":{
        "arch":"x86",
        "version":22,
        "year":2012
    }
},
{
    "name":"Mongo",
    "type":"db",
    "release":{
        "arch":"x64",
        "version":21,
        "year":2012
    }
},
{
    "name":"Mongo",
    "type":"db",
    "release":{
        "arch":"x86",
        "version":23,
        "year":2013
    }
},      
{
    "key":"Diffrent",
    "value":"cool",
    "children":{
        "tech":"json",
        "lang":"php",
        "year":2013
    }
}
]';

$array = json_decode($json, true);

उदाहरण 1

जांचें कि क्या key - Different जितना आसान होगा

echo new ArrayCollection($array, array("key" => "Diffrent"));

आउटपुट

{"3":{"key":"Diffrent","value":"cool","children":{"tech":"json","lang":"php","year":2013}}}

उदाहरण 2 जांचें कि क्या release year है 2013

echo new ArrayCollection($array, array("release.year" => 2013));

आउटपुट

{"2":{"name":"Mongo","type":"db","release":{"arch":"x86","version":23,"year":2013}}}

उदाहरण 3

गिनें जहां Year है 2012

$c = new ArrayCollection($array, array("release.year" => 2012));
echo count($c); // output 2 

उदाहरण 4

आइए आपके उदाहरण से लेते हैं जहां आप version check की जांच करना चाहते हैं grater than 22 . है

$c = new ArrayCollection($array, array("release.version" => array('$gt'=>22)));
echo $c;

आउटपुट

{"2":{"name":"Mongo","type":"db","release":{"arch":"x86","version":23,"year":2013}}}

उदाहरण 5

जांचें कि क्या release.arch मान IN है एक सेट जैसे [x86,x100] (उदाहरण)

$c = new ArrayCollection($array, array("release.arch" => array('$in'=>array("x86","x100"))));
foreach($c as $var)
{
    print_r($var);
}

आउटपुट

Array
(
    [name] => Mongo
    [type] => db
    [release] => Array
        (
            [arch] => x86
            [version] => 22
            [year] => 2012
        )

)
Array
(
    [name] => Mongo
    [type] => db
    [release] => Array
        (
            [arch] => x86
            [version] => 23
            [year] => 2013
        )

)

उदाहरण 6

कॉल करने योग्य का उपयोग करना

$year = 2013;
$expression = array("release.year" => array('$func' => function ($value) use($year) {
    return $value === 2013;
}));

$c = new ArrayCollection($array, $expression);

foreach ( $c as $var ) {
    print_r($var);
}

आउटपुट

Array
(
    [name] => Mongo
    [type] => db
    [release] => Array
        (
            [arch] => x86
            [version] => 23
            [year] => 2013
        )

)

उदाहरण 7

अपना स्वयं का अभिव्यक्ति नाम पंजीकृत करें

$c = new ArrayCollection($array, array("release.year" => array('$baba' => 3)), false);
$c->register('$baba', function ($a, $b) {
    return substr($a, - 1) == $b;
});
$c->parse();
echo $c;

आउटपुट

{"2":{"name":"Mongo","type":"db","release":{"arch":"x86","version":23,"year":2013}}}

प्रयुक्त वर्ग

class ArrayCollection implements IteratorAggregate, Countable, JsonSerializable {
    private $array;
    private $found = array();
    private $log;
    private $expression;
    private $register;

    function __construct(array $array, array $expression, $parse = true) {
        $this->array = $array;
        $this->expression = $expression;
        $this->registerDefault();
        $parse === true and $this->parse();
    }

    public function __toString() {
        return $this->jsonSerialize();
    }

    public function jsonSerialize() {
        return json_encode($this->found);
    }

    public function getIterator() {
        return new ArrayIterator($this->found);
    }

    public function count() {
        return count($this->found);
    }

    public function getLog() {
        return $this->log;
    }

    public function register($offset, $value) {
        if (strpos($offset, '$') !== 0)
            throw new InvalidArgumentException('Expresiion name must always start with "$" sign');

        if (isset($this->register[$offset]))
            throw new InvalidArgumentException(sprintf('Expression %s already registred .. Please unregister It first'));

        if (! is_callable($value)) {
            throw new InvalidArgumentException(sprintf('Only callable value can be registred'));
        }

        $this->register[$offset] = $value;
    }

    public function unRegister($offset) {
        unset($this->register[$offset]);
    }

    public function parse() {
        $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($this->array));
        foreach ( $it as $k => $items ) {
            if ($this->evaluate($this->getPath($it), $items)) {
                $this->found[$it->getSubIterator(0)->key()] = $this->array[$it->getSubIterator(0)->key()];
            }
        }
    }

    private function registerDefault() {
        $this->register['$eq'] = array($this,"evaluateEqal");
        $this->register['$not'] = array($this,"evaluateNotEqual");

        $this->register['$gte'] = array($this,"evaluateGreater");
        $this->register['$gt'] = array($this,"evaluateGreater");

        $this->register['$lte'] = array($this,"evaluateLess");
        $this->register['$lt'] = array($this,"evaluateLess");

        $this->register['$in'] = array($this,"evalueateInset");

        $this->register['$func'] = array($this,"evalueateFunction");
        $this->register['$fn'] = array($this,"evalueateFunction");
        $this->register['$f'] = array($this,"evalueateFunction");
    }

    private function log($log) {
        $this->log[] = $log;
    }

    private function getPath(RecursiveIteratorIterator $it) {
        $keyPath = array();
        foreach ( range(1, $it->getDepth()) as $depth ) {
            $keyPath[] = $it->getSubIterator($depth)->key();
        }
        return implode(".", $keyPath);
    }

    private function checkType($a, $b) {
        if (gettype($a) != gettype($b)) {
            $this->log(sprintf("%s - %s  is not same type of %s - %s", json_encode($a), gettype($a), json_encode($b), gettype($b)));
            return false;
        }
        return true;
    }

    private function evaluate($key, $value) {
        $o = $r = 0; // Obigation & Requirement
        foreach ( $this->expression as $k => $options ) {
            if ($k !== $key)
                continue;

            if (is_array($options)) {
                foreach ( $options as $eK => $eValue ) {
                    if (strpos($eK, '$') === 0) {
                        $r ++;
                        $callable = $this->register[$eK];
                        $callable($value, $eValue) and $o ++;
                    } else {
                        throw new InvalidArgumentException('Missing "$" in expession key');
                    }
                }
            } else {

                $r ++;
                $this->evaluateEqal($value, $options) and $o ++;
            }
        }
        return $r > 0 && $o === $r;
    }

    private function evaluateEqal($a, $b) {
        return $a == $b;
    }

    private function evaluateNotEqual($a, $b) {
        return $a != $b;
    }

    private function evaluateLess($a, $b) {
        return $this->checkType($a, $b) and $a < $b;
    }

    private function evaluateGreater($a, $b) {
        return $this->checkType($a, $b) and $a > $b;
    }

    private function evalueateInset($a, array $b) {
        return in_array($a, $b);
    }

    private function evalueateFunction($a, callable $b) {
        return $b($a);
    }
}

सारांश

<ब्लॉकक्वॉट>

इसमें सभी उन्नत सुविधाएँ शामिल नहीं हो सकती हैं, और इसमें एक्स्टेंसिबल आर्किटेक्चर होना चाहिए

उपरोक्त वर्ग आप जो चाहते हैं उसका एक विशिष्ट उदाहरण दिखाता है .. आप आसान कर सकते हैं decouple it , इसे $and . जैसे यौगिक अभिव्यक्तियों का समर्थन करने के लिए विस्तारित करें और $or

<ब्लॉकक्वॉट>

MongoDB जैसी क्वेरी एक्सप्रेशन ऑब्जेक्ट समझने और उपयोग करने के लिए आसान हैं, स्वच्छ, आत्म-व्याख्या कोड लिखने की क्षमता प्रदान करते हैं, क्योंकि क्वेरी और ऑब्जेक्ट दोनों में खोज करने के लिए सहयोगी सरणियाँ हैं।

क्यों न केवल एक MongoDB के लिए सरणी लिखें डेटाबेस काम करने के बजाय इसे सरणियाँ ?? यह अधिक कुशल है और यह आपको बहुत सारी परेशानियों से बचाएगा

मुझे यह भी उल्लेख करना चाहिए कि सर्वोत्तम कार्य के लिए सर्वोत्तम उपकरण का उपयोग करें ... आप जो चाहते हैं वह मूल रूप से एक डेटाबेस का कार्य है

<ब्लॉकक्वॉट>

मूल रूप से PHP सरणियों से जानकारी निकालने के लिए यह एक सुविधाजनक कार्य है। सरणी संरचना (एरेपाथ) को जानने के बाद, यह कई नेस्टेड लूप की आवश्यकता के बिना बहुआयामी सरणी डेटा पर संचालन करने की अनुमति देगा।

उदाहरण दिखाता है कि मूल्य की खोज के लिए पथ का उपयोग कैसे किया जाता है लेकिन आप अभी भी सरणी को स्मृति में लोड करने पर निर्भर हैं और आपकी कक्षा एकाधिक रिकर्सन उत्तर लूप कर रही है जो डेटाबेस के रूप में कुशल नहीं है।

<ब्लॉकक्वॉट>

मैं आर्किटेक्चर टिप्स, संबंधित या समान कोड की सराहना करता हूं, जो फ्लाई पर PHP "if..else" अभिव्यक्तियों के निर्माण के लिए एक अच्छा अभ्यास उदाहरण हो सकता है।

क्या आपका वास्तव में मतलब है कि आप वे सभी यहां चाहते हैं ???



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB मानचित्र में चर का उपयोग कैसे करें- मानचित्र फ़ंक्शन को कम करें

  2. कैसे एक कॉल के साथ नेवला में एक सरणी में वस्तुओं की एक सरणी पुश करने के लिए?

  3. php mongodb संग्रह में nth प्रविष्टि खोजें

  4. Has_many को कैसे कार्यान्वित करें:मोंगोइड और मोंगोडब के साथ संबंधों के माध्यम से?

  5. Mongo id डरावने URL की ओर ले जाती है