20277


MySQLなどのSQL構文では下記のように

$sql = "SELECT * FROM TABLE WHERE hoge = 1 AND (piyo BETWEEN 1 AND 12) OR
(fuga BETWEEN 1 AND 10)

複数条件は簡単に出来ますがPHP＋MongoDBでの複数指定がわかりません。  
単体での指定はよく使っていますが、上記のような複数指定が必要な場面が出てきて詰まっています。  
shellからではなくPHP構文での指定の仕方が知りたいのですが教えていただけないでしょうか。


CC BY-SA 3.0
2015-09-28T16:42:12.573
17038
2017-08-22T17:16:27.567
7852
question
php mongodb
PHP＋MongoDBでBetween条件を複数使いたい


PHP を使っても MongoDB のクエリを理解する必要があるため、コンソール（javascript）の実行とPHPの記述方法の両方を説明します。

まず、MongoDB で使えるクエリは以下のようなものがあります。  
<https://docs.mongodb.org/manual/reference/operator/query/>

betweenクエリは無いので、`$gte`（以上）、`$lt`（未満）などを使ってクエリを記述します。  
また、OR条件を記述するために `$or` クエリを用います。

実例を交えて説明したいため、最初にテストデータを入れておきます。  
具体的には以下のように mongo shell で実行します。

[code]

    for (var i = 0; i < 100; i++) { db.mycollection.insert({hoge: i+1}) }
    db.mycollection.find();
    
[/code]

すると、hogeフィールドに1〜100の値を持つドキュメント（レコード）が入ります。

[code]

    { "_id" : ObjectId("5678bcb68213e2158ab5bf1b"), "hoge" : 1 }
    { "_id" : ObjectId("5678bcb68213e2158ab5bf1c"), "hoge" : 2 }
        :
        :
    { "_id" : ObjectId("5678bcb68213e2158ab5c301"), "hoge" : 99 }
    { "_id" : ObjectId("5678bcb68213e2158ab5c302"), "hoge" : 100 }
    
[/code]

最初に、`$gte` と `$lt` クエリを用いて between 検索を行ってみます。  
mongo shell では以下のようになります。

[code]

    db.mycollection.find(
      {hoge: {$gte: 5, $lt: 10}}
    );
    
    { "_id" : ObjectId("5678bcb68213e2158ab5bf1f"), "hoge" : 5 }
    { "_id" : ObjectId("5678bcb68213e2158ab5bf20"), "hoge" : 6 }
    { "_id" : ObjectId("5678bcb68213e2158ab5bf21"), "hoge" : 7 }
    { "_id" : ObjectId("5678bcb68213e2158ab5bf22"), "hoge" : 8 }
    { "_id" : ObjectId("5678bcb68213e2158ab5bf23"), "hoge" : 9 }
    
[/code]

次に、`$or` クエリで複数のクエリを検索するには、以下のようになります。

[code]

    db.mycollection.find({
      $or: [
        {hoge: {$gte: 5, $lt: 10}},
        {hoge: {$gte: 90, $lt: 95}}
      ]
    });
    
    { "_id" : ObjectId("5678bcb68213e2158ab5bf1f"), "hoge" : 5 }
    { "_id" : ObjectId("5678bcb68213e2158ab5bf20"), "hoge" : 6 }
    { "_id" : ObjectId("5678bcb68213e2158ab5bf21"), "hoge" : 7 }
    { "_id" : ObjectId("5678bcb68213e2158ab5bf22"), "hoge" : 8 }
    { "_id" : ObjectId("5678bcb68213e2158ab5bf23"), "hoge" : 9 }
    { "_id" : ObjectId("5678bcb68213e2158ab5bf74"), "hoge" : 90 }
    { "_id" : ObjectId("5678bcb68213e2158ab5bf75"), "hoge" : 91 }
    { "_id" : ObjectId("5678bcb68213e2158ab5bf76"), "hoge" : 92 }
    { "_id" : ObjectId("5678bcb68213e2158ab5bf77"), "hoge" : 93 }
    { "_id" : ObjectId("5678bcb68213e2158ab5bf78"), "hoge" : 94 }
    
[/code]

このクエリをそのまま PHP で書けばいいのですが、[PHP mongodbドライバ](http://php.net/mongodb) と [PHP
ライブラリ](http://php.net/manual/ja/mongodb.tutorial.library.php)
を用いると以下のように記述できます。

[code]

    <?php
    require 'vendor/autoload.php';
    
    $manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
    $collection = new MongoDB\Collection($manager, "mydb.mycollection");
    
    $result = $collection->find(
        ['hoge' => ['$gte' => 5, '$lt' => 10]]
    );
    
    foreach ($result as $entry) {
        echo $entry->_id, ': ', $entry->hoge, "\n";
    }
    //5678bcb68213e2158ab5bf1f: 5
    //5678bcb68213e2158ab5bf20: 6
    //5678bcb68213e2158ab5bf21: 7
    //5678bcb68213e2158ab5bf22: 8
    //5678bcb68213e2158ab5bf23: 9
    
    echo "----------------\n\n";
    
    $result = $collection->find([
        '$or' => [
            ['hoge' => ['$gte' => 5, '$lt' => 10]],
            ['hoge' => ['$gte' => 90, '$lt' => 95]],
        ]
    ]);
    
    foreach ($result as $entry) {
        echo $entry->_id, ': ', $entry->hoge, "\n";
    }
    
    //5678bcb68213e2158ab5bf1f: 5
    //5678bcb68213e2158ab5bf20: 6
    //5678bcb68213e2158ab5bf21: 7
    //5678bcb68213e2158ab5bf22: 8
    //5678bcb68213e2158ab5bf23: 9
    //5678bcb68213e2158ab5bf74: 90
    //5678bcb68213e2158ab5bf75: 91
    //5678bcb68213e2158ab5bf76: 92
    //5678bcb68213e2158ab5bf77: 93
    //5678bcb68213e2158ab5bf78: 94
    
[/code]

このように mongo shell で使えるクエリと同じように PHP でクエリを投げることで期待の結果を得られるかと思います。


CC BY-SA 3.0
2015-12-22T04:31:44.940
20277
2015-12-22T04:31:44.940
2944
17038
answer