mongodb php - 如何做“INNER JOIN”式查询

时间:2010-09-30 10:18:20

标签: 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"
}

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

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

5 个答案:

答案 0 :(得分: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"
                }]
    }

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

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

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

我希望这有用。

答案 1 :(得分:14)

忘记加入。

查找您的新闻。应用跳过编号和限制来分页结果。

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

然后遍历集合并在此示例中获取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] } } ); 

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

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

答案 2 :(得分:4)

您可能最好在用户文档中嵌入“新闻”。

答案 3 :(得分:4)

如果您使用的是新版本的MongoDB(3.2),那么您可以使用 $lookup 运算符获得类似内容。

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

View Controller集合上的以下聚合操作使用URL中的WebView字段将news中的文档与news集合中的文档相连接集合和users集合中的user_id字段:

news

等效的PHP示例实现:

_id

答案 4 :(得分:0)

你不能在mongoDB中这样做。从版本3开始,不推荐使用Eval(),因此您也不应该使用存储过程。

我知道实现涉及多个集合的服务器端查询的唯一方法就是使用Node.js或类似方法。但是,如果您打算尝试这种方法,我强烈建议您出于安全原因限制允许访问您的计算机的IP地址。

另外,如果你的收藏品不是太大,你可以避免内部连接使它们非规范化。