2010-09-30 5 views
8

Tôi đang sử dụng phần mở rộng Mongo PHP.mongodb php - cách thực hiện "INNER JOIN" giống như truy vấn

Dữ liệu của tôi trông giống như:

users 
{ 
    "_id": "4ca30369fd0e910ecc000006", 
    "login": "user11", 
    "pass": "example_pass", 
    "date": "2010-09-29" 
}, 
{ 
    "_id": "4ca30373fd0e910ecc000007", 
    "login": "user22", 
    "pass": "example_pass", 
    "date": "2010-09-29" 
} 

news 
{ 
    "_id": "4ca305c2fd0e910ecc000003", 
    "name": "news 333", 
    "content": "news content 3333", 
    "user_id": "4ca30373fd0e910ecc000007", 
    "date": "2010-09-29" 
}, 
{ 
    "_id": "4ca305c2fd0e910ecc00000b", 
    "name": "news 222", 
    "content": "news content 2222", 
    "user_id": "4ca30373fd0e910ecc000007", 
    "date": "2010-09-29" 
}, 
{ 
    "_id": "4ca305b5fd0e910ecc00000a", 
    "name": "news 111", 
    "content": "news content", 
    "user_id": "4ca30369fd0e910ecc000006", 
    "date": "2010-09-29" 
} 

Làm thế nào để chạy một truy vấn tương tự như thế này, từ PHP?

SELECT n.*, u.* 
FROM news AS n 
INNER JOIN users AS u ON n.user_id = u.id 

Trả lời

4

Bạn có thể nên nhúng "tin tức" trong tài liệu của người dùng.

+0

câu trả lời hay nhất, nosql là tất cả về lettin Những điều cần thiết cho các cấu trúc mới đến với cuộc sống –

18

MongoDB không hỗ trợ kết nối. Nếu bạn muốn ánh xạ người dùng tới tin tức, bạn có thể làm như sau

1) Làm điều này ở lớp ứng dụng. Nhận danh sách người dùng và nhận danh sách tin tức cũng như ánh xạ chúng trong ứng dụng của bạn. Phương pháp này rất tốn kém nếu bạn cần điều này thường xuyên.

2) Nếu bạn cần thực hiện bước trước đó thường xuyên, bạn nên thiết kế lại lược đồ của mình để các bài viết tin tức được lưu trữ dưới dạng tài liệu nhúng cùng với tài liệu người dùng.

{ 
     "_id": "4ca30373fd0e910ecc000007", 
     "login": "user22", 
     "pass": "example_pass", 
     "date": "2010-09-29" 
     "news" : [{ 
        "name": "news 222", 
        "content": "news content 2222", 
        "date": "2010-09-29" 
       }, 
       { 
        "name": "news 222", 
        "content": "news content 2222", 
        "date": "2010-09-29" 
       }] 
    } 

Khi bạn có dữ liệu ở định dạng này, truy vấn mà bạn đang cố chạy là ẩn. Tuy nhiên, một điều cần lưu ý là các truy vấn phân tích trở nên khó khăn trên lược đồ như vậy. Bạn sẽ cần sử dụng MapReduce để nhận các bài viết tin tức được thêm gần đây nhất và các truy vấn như vậy.

Cuối cùng thiết kế lược đồ và mức độ không chuẩn hóa mà ứng dụng của bạn có thể xử lý phụ thuộc vào loại truy vấn bạn mong đợi ứng dụng của mình chạy.

Bạn có thể thấy các liên kết này hữu ích. http://www.mongodb.org/display/DOCS/Schema+Design http://www.blip.tv/file/3704083

Tôi hy vọng điều đó hữu ích.

+0

Nếu bạn đang lưu trữ toàn bộ các bài viết tin tức được nhúng với người dùng của mình, thì lưu trữ đối tượng 4MB có phải là mối quan ngại không? – jocull

+0

Bạn có thể sử dụng dbrefs thay vì tài liệu thực tế http://docs.mongodb.org/manual/applications/database-references/ – Optimus

14

Quên tham gia.

thực hiện tìm kiếm tin tức của bạn. Áp dụng số bỏ qua và giới hạn cho phân trang kết quả.

$newscollection->find().skip(20).limit(10); 

sau đó vòng qua bộ sưu tập và lấy user_id trong ví dụ này, bạn sẽ bị giới hạn trong 10 mục. Bây giờ làm một truy vấn trên người dùng cho các mặt hàng user_id tìm thấy.

// replace 1,2,3,4 with array of userids you found in the news collection. 
$usercollection.find({ _id : { $in : [1,2,3,4] } }); 

Sau đó, khi bạn in ra, tin tức có thể hiển thị thông tin người dùng từ bộ sưu tập người dùng dựa trên user_id.

Bạn đã thực hiện 2 truy vấn vào cơ sở dữ liệu. Không lộn xộn xung quanh với sự tham gia và tìm ra tên trường vv ĐƠN GIẢN !!!

0

Bạn không thể làm điều đó trong mongoDB. Và từ phiên bản 3 Đánh giá() không được chấp nhận, vì vậy bạn không nên sử dụng các thủ tục được lưu trữ.

Cách duy nhất tôi biết để đạt được truy vấn phía máy chủ liên quan đến nhiều bộ sưu tập ngay bây giờ là sử dụng Node.js hoặc tương tự. Nhưng nếu bạn đang thử phương pháp này, tôi khuyên bạn nên hạn chế các địa chỉ ip được phép truy cập máy tính của bạn, vì lý do bảo mật.

Ngoài ra, nếu bộ sưu tập của bạn không quá lớn, bạn có thể tránh các tham gia bên trong làm mất bình thường hóa chúng.

4

Nếu bạn đang sử dụng phiên bản mới của MongoDB (3.2), sau đó bạn sẽ nhận được một cái gì đó tương tự với các nhà điều hành $lookup có thể được so sánh với một trái bên ngoài tham gia vào SQL. Những hạn chế với việc sử dụng toán tử này là nó không hiệu quả cao khi chạy trên các tập kết quả lớn và nó chỉ hỗ trợ bình đẳng cho trận đấu mà sự bình đẳng phải nằm giữa một khóa duy nhất từ ​​mỗi bộ sưu tập. Giới hạn khác là bộ sưu tập quyền phải là một bộ sưu tập không bị quản lý trong cùng một cơ sở dữ liệu như bộ sưu tập bên trái.

Các hoạt động tập hợp sau đây về tình hình thu news gia nhập tài liệu từ news với các tài liệu từ bộ sưu tập users sử dụng các lĩnh vực user_id từ bộ sưu tập news_id trường từ users bộ sưu tập:

db.news.aggregate([ 
    { 
     "$lookup": { 
      "from": "users", 
      "localField": "user_id", 
      "foreignField": "_id", 
      "as": "user_docs" 
     } 
    } 
]) 

Tương đương Triển khai ví dụ PHP:

<?php 
$m = new MongoClient("localhost"); 
$c = $m->selectDB("test")->selectCollection("news"); 
$ops = array(
    array(
     "$lookup" => array(
      "from" => "users", 
      "localField" => "user_id", 
      "foreignField" => "_id", 
      "as" => "user_docs" 
     ) 
    ) 
); 
$results = $c->aggregate($ops); 
var_dump($results); 
?>