如何在MongoDB中交叉引用数据

时间:2013-02-19 02:59:58

标签: php mongodb mongodb-php

我正在尝试使用PHP和MongoDB创建我的第一个应用程序。

我想要的是一个特定区域的果树列表,而且我想要一个可以在一个区域种植的果树列表。

我来自MySQL背景,所以如果在sql中,我会有一个树表,其中包含有关树的信息。比我有一张实际树木的表格,它将与树木表格一起留在ID上,并且还有位置和其他信息。

然而在Mongo中,我不确定这是怎么做的,或者它应该如何完成。

Baiscally希望我想要的是一个树的列表,并且比用户可以对自己的树做出参考。

有关如何做到这一点的任何帮助或指示。

$db->trees->fruittrees
$db->tress->userstrees 

克里斯

3 个答案:

答案 0 :(得分:1)

然而,你的问题中遗漏了很多东西:

  

我想要的是一个特定区域的果树列表,而且我想要一个可以在一个区域种植的果树列表。

闻起来像地理空间查询:http://docs.mongodb.org/manual/core/geospatial-indexes/

因此用户将拥有一个位置:

{
    name: 'sammaye',
    location: [107,206]
}

每棵正在成长的树都可以利用一系列区域:

{
    name: 'apple tree'
    locations_of_growth: [[74,59],[67,-45]]
}

您只需对用户进行$near查询,与地球的距离(http://docs.mongodb.org/manual/core/geospatial-indexes/#distance-calculation)相比,即可计算该用户附近存在的树木。

关于地理空间查询的问题是,它们也可以被更多信息约束,所以说你想让用户比较该地区苹果树的叶子颜色,以找出该地区有多少苹果树有了绿叶,您只需将其添加为树文档中的conditiojn并将其添加到$near

地理空间查询有一个缺点,那就是每个集合只能有一个索引(http://docs.mongodb.org/manual/core/geospatial-indexes/#create-a-geospatial-index)所以这意味着如果你还想提供一个可以种植的树的列表区域然后您可能需要两个集合,一个名为other_trees,一个名为growable_species。如果您希望允许用户将其树与您查询other_trees区域中的其他树进行比较,并且当您希望允许用户查看该区域中可以生长的树时,您可以查询growable_trees

这当然只是这样做的一种方式。

修改

我不会“推荐”使用Doctrine,它取决于你的情况。 Doctrine是一个非常繁重且速度惊人的ORM,并且有很多更快,更轻量级的ORM用于PHP:http://docs.mongodb.org/ecosystem/drivers/php-libraries/如果你想使用ORM,也许你有一个完整的堆栈框架或者你我想和司机一起去。

MongoDB也不需要JSON PHP(无论如何)处理知识。 MongoDB的所有结果都作为BSON进入驱动程序,然后被反序列化为PHP中的标准dict,即关联数组。这里不需要JSON PHP处理知识。

与其他答案不同,要非常谨慎“将所有信息存储在单个JSON文档中”,即因为MongoDB是BSON而不是JSON,而且因为嵌入应该非常仔细地考虑,应该判断它是否适合你的场景与否。事实上,您会发现在大多数情况下将_id以外的任何内容嵌入到其他行中可能会导致问题,但正如我所说它依赖于场景。

答案 1 :(得分:0)

MongoDB是面向文档的数据库。这意味着您应该在MySQL或其他关系数据库中使用完全不同的模型。例如,如果要存储用户信息(包括他们拥有的树),则应将所有信息存储在单个JSON文档中。如需更多参考,请阅读this

我还建议使用Doctrine,它允许您将对象存储到MongoDB中,因此对数据库建模要容易得多,您只需要创建一个代表您的对象的面向对象的模型。请参阅this page

为此,您将需要JSON php处理和面向对象编程方面的知识。从使用MySql到No-Sql数据库的过渡开始总是有一件事是建模数据库然后denormalize表,这样你就会知道放入对象所需的所有信息/文档。

希望这有助于你

答案 2 :(得分:0)

我经常在Mongo中建模数据时发现它取决于你将如何在UI中使用数据。 Mongo不擅长连接(如你所知),但你仍然可以做到。您可以在中间层或UI中执行它们。

因此,对于您的示例,我可能会执行以下操作:

树集合中的树:


{
   "_id" : 123,
   "name" : "Orange",
   "price" : 10,
   "climate" : "Any"
}

用户:


{
   "user" : "Bob",
   "selected_trees" : [ 123, 124, 156 ]
}

然后在您的UI中,加载Bob并对可用的树集合进行一次调用,以获取树的详细信息。

通常的做法是实际包含用户的完整树对象。对于来自关系背景的这个想法,你会厌恶地反感,但它与Mongo非常相似。你有全部相同数据的副本。这是正常的和预期的。