Hướng dẫn dùng query mongodb trong PHP

Bài trước, mình đã giới thiệu với mọi người cách update documnent trong mongodb rồi. Tiếp tục với bài này mình sẽ giới thiệu với mọi người cách query lấy dữ liệu trong MongoDB ra sử dụng PHP.

Show

Trong bài viết này mình sẽ demo trên data mẫu như sau:

Hướng dẫn dùng query mongodb trong PHP

Để có thể query dữ liệu trong MongoDB ra thì chúng ta sẽ sử dụng 2 phương thức find()findOne() với chức năng và cách sử dụng chi tiết như sau:

1, findOne()

- Phương thức này cho phép chúng ta truy vấn và trả về lớn nhất 1 bản ghi. Nó tương tự như câu truy vấn sau trong SQL.

SELECT somthing FROM tableName WHERE LIMIT 1;

Cú pháp sử dụng phương thức findOne() như sau:

$collection->findOne($filter, $options);

Trong đó:

  • $filter là một array hoặc mảng chứa các điều kiện mà bạn muốn truy vấn.
  • $option là một mảng chứa các thông số cấu hình thêm như chỉ định các trường được lấy ra (select) hoăc limit,... (có thể bỏ trống).

VD: Trong ví dụ sau mình sẽ thử truy vấn document có category = 'Foo'.

tuts;

//select collection
$post = $db->Post;

//Query
$result = $post->findOne(['category' => 'Foo']);

var_dump($result);

Và đây là kết quả trả về:

object(MongoDB\Model\BSONDocument)#17 (1) {
  ["storage":"ArrayObject":private]=>
  array(4) {
    ["_id"]=>
    object(MongoDB\BSON\ObjectId)#16 (1) {
      ["oid"]=>
      string(24) "5acf3796350ec622e218deb3"
    }
    ["title"]=>
    string(8) "Foo Post"
    ["content"]=>
    string(208) "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odio harum necessitatibus eius magnam, doloribus explicabo omnis natus alias, nisi dolorum ea ab. Nobis quo magnam aliquid molestias, ipsum nihil eum."
    ["category"]=>
    string(3) "Foo"
  }
}

Như các bạn đã thấy thì mặc dù trong database (database demo ở trên) có 2 document có category là "Foo" nhưng khi chúng ta sử dụng findOne() nó chỉ trả về duy nhất một bản ghi đầu tiên mà nó lấy được.

Và nếu muốn lấy giá trị của document thì chỉ cần trỏ $result đến các key trong database là được (ORM mapping).
VD:

tuts;

//select collection
$post = $db->Post;

//Query
$result = $post->findOne(['category' => 'Foo']);

$result->title; // Foo Post

$result->content; // Lorem ipsum dolor sit amet ...

$result->category; // Foo

2, find().

Phương thức này cũng tương tự như phương thức findOne(), nhưng phương thức này sẽ trả về tất cả dữ liệu mà nó so khớp với $filter.

VD:  Cũng với câu query ở phần 1 nhưng giờ mình sẽ sử dụng phương thức find().

tuts;

//select collection
$post = $db->Post;

//Query
$result = $post->find(['category' => 'Foo']);

var_dump($result);

Và đây là kết quả trả về:

object(MongoDB\Driver\Cursor)#13 (9) {
  ["database"]=>
  string(4) "tuts"
  ["collection"]=>
  string(4) "Post"
  ["query"]=>
  object(MongoDB\Driver\Query)#12 (3) {
    ["filter"]=>
    object(stdClass)#10 (1) {
      ["category"]=>
      string(3) "Foo"
    }
    ["options"]=>
    object(stdClass)#14 (1) {
      ["serverId"]=>
      int(1)
    }
    ["readConcern"]=>
    NULL
  }
  ["command"]=>
  NULL
  ["readPreference"]=>
  object(MongoDB\Driver\ReadPreference)#7 (1) {
    ["mode"]=>
    string(7) "primary"
  }
  ["isDead"]=>
  bool(false)
  ["currentIndex"]=>
  int(0)
  ["currentDocument"]=>
  NULL
  ["server"]=>
  object(MongoDB\Driver\Server)#11 (10) {
    ["host"]=>
    string(9) "127.0.0.1"
    ["port"]=>
    int(37017)
    ["type"]=>
    int(1)
    ["is_primary"]=>
    bool(false)
    ["is_secondary"]=>
    bool(false)
    ["is_arbiter"]=>
    bool(false)
    ["is_hidden"]=>
    bool(false)
    ["is_passive"]=>
    bool(false)
    ["last_is_master"]=>
    array(10) {
      ["ismaster"]=>
      bool(true)
      ["maxBsonObjectSize"]=>
      int(16777216)
      ["maxMessageSizeBytes"]=>
      int(48000000)
      ["maxWriteBatchSize"]=>
      int(100000)
      ["localTime"]=>
      object(MongoDB\BSON\UTCDateTime)#14 (1) {
        ["milliseconds"]=>
        string(13) "1523531925335"
      }
      ["logicalSessionTimeoutMinutes"]=>
      int(30)
      ["minWireVersion"]=>
      int(0)
      ["maxWireVersion"]=>
      int(6)
      ["readOnly"]=>
      bool(false)
      ["ok"]=>
      float(1)
    }
    ["round_trip_time"]=>
    int(0)
  }
}

Như các bạn đã thấy thì nó trả về một loạt các thông tin, nhưng lại không thấy kết quả trả về là gì? Để lấy kết quả trả về các bạn chỉ cần vứt object $result bỏ vào vòng lặp foreach như sau:

foreach ($result as $row) {
    $row->title; //title
    $row->category; // category
    // ...
}

Hoặc bạn cũng có thể gọi phương thức toArray() để convert result thành mảng. Mảng này sẽ chứa các Bson Object với mỗi một BsonObject là một document.

VD:

print_r($result->toArray());

Kết quả trả về.

Array
(
    [0] => MongoDB\Model\BSONDocument Object
        (
            [storage:ArrayObject:private] => Array
                (
                    [_id] => MongoDB\BSON\ObjectId Object
                        (
                            [oid] => 5acf3796350ec622e218deb3
                        )

                    [title] => Foo Post
                    [content] => Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odio harum necessitatibus eius magnam, doloribus explicabo omnis natus alias, nisi dolorum ea ab. Nobis quo magnam aliquid molestias, ipsum nihil eum.
                    [category] => Foo
                )

        )

    [1] => MongoDB\Model\BSONDocument Object
        (
            [storage:ArrayObject:private] => Array
                (
                    [_id] => MongoDB\BSON\ObjectId Object
                        (
                            [oid] => 5acf3906350ec622e218deb5
                        )

                    [title] => Foo Post 2
                    [content] => Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odio harum necessitatibus eius magnam, doloribus explicabo omnis natus alias, nisi dolorum ea ab. Nobis quo magnam aliquid molestias, ipsum nihil eum.
                    [category] => Foo
                )

        )

)

3, Các ví dụ khác.

Về phần $filter chứa các tham số điều kiện gì thì các bạn có thể tham khảo bài viết này nó hoàn toàn giống như thế.

VD: Lấy ra title của các document có category = 'Foo'.

tuts->Post;

$result = $post->find(
    [
        'category' => 'Foo'
    ],
    [
        'projection' => [
            'title' => '1'
        ]
    ]
);

var_dump($result->toArray());

// Câu trên tương tự với câu truy vấn SQL sau:
// SELECT title FROM Post WHERE category = 'Foo'

VD: Tìm kiếm document có tile chứa số 2.

tuts->Post;

$result = $post->find(
    [
        'title' => ['$regex' => '2', '$options'=> 'i']
    ]
);

var_dump($result->toArray());

// Câu trên tương tự với câu truy vấn SQL sau:
// SELECT * FROM Post WHERE title LIKE '%2%'

VD: Lấy ra 2 bản ghi trong collection.

tuts->Post;

$result = $post->find([], ['limit' => 2]);

var_dump($result->toArray());

// Câu trên tương tự với câu truy vấn SQL sau:
// SELECT * FROM Post LIMIT 2

VD: Lấy ra 2 bản ghi bắt đầu từ bản ghi thứ nhất.

tuts->Post;

$result = $post->find([], [
    'limit' => 2,
    'skip' => 1
]);

var_dump($result->toArray());

// Câu trên tương tự với câu truy vấn SQL sau:
// SELECT * FROM Post LIMIT 1,2

,...

4, Kết.

Bài này mình chỉ demo một phần nhỏ các case query trong MongoDB thôi, để xem thêm các bạn có thể tham khảo bài này hoặc lên docs của MongoDB.