mongodb php - 如何做"INNER JOIN"式查询

per*_*ten 8 mongodb mongodb-php

我正在使用Mongo PHP扩展.

我的数据如下:

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"
}
Run Code Online (Sandbox Code Playgroud)

如何从PHP运行类似这样的查询?

SELECT n.*, u.* 
FROM news AS n 
INNER JOIN users AS u ON n.user_id = u.id
Run Code Online (Sandbox Code Playgroud)

sri*_*ani 19

MongoDB不支持连接.如果要将用户映射到新闻,可以执行以下操作

1)在应用层执行此操作.获取用户列表,获取新闻列表并将其映射到您的应用程序中.如果您经常需要这种方法,这种方法非常昂贵.

2)如果您需要经常执行上一步,则应重新设计架构,以便将新闻文章与用户文档一起存储为嵌入式文档.

    {
      "_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"
                }]
    }
Run Code Online (Sandbox Code Playgroud)

以这种格式获取数据后,您尝试运行的查询是隐式的.但有一点需要注意的是,分析查询在这种模式上变得困难.您需要使用MapReduce来获取最近添加的新闻文章和此类查询.

最后,模式设计和应用程序可以处理多少非规范化取决于您希望应用程序运行的查询类型.

您可能会发现这些链接很有用. http://www.mongodb.org/display/DOCS/Schema+Design http://www.blip.tv/file/3704083

我希望这很有帮助.


Ric*_*ato 14

忘了加入.

找到你的新闻.应用跳过编号和限制以分页结果.

$newscollection->find().skip(20).limit(10);
Run Code Online (Sandbox Code Playgroud)

然后循环遍历集合并在此示例中获取user_id,您将限制为10个项目.现在对找到的user_id项目的用户进行查询.

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

然后,当您打印出新闻时,它可以根据user_id显示用户集合中的用户信息.

您对数据库进行了2次查询.没有乱搞连接和搞清楚字段名称等简单!!!


chr*_*dam 5

如果您使用的是新版本的 MongoDB (3.2),那么您将获得与$lookup操作符类似的内容。

使用此运算符的缺点是在运行大型结果集时效率非常低,并且它仅支持匹配的相等性,其中相等性必须在每个集合的单个键之间。另一个限制是右集合应该是与左集合位于同一数据库中的未分片集合。

在下面的聚合操作news系列外,从文件news从文件users使用的字段集合user_idnews收集和_id从外地users收集:

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

等效的 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);
?>
Run Code Online (Sandbox Code Playgroud)


luc*_*axi 4

您最好将“新闻”嵌入到用户的文档中。