【问题标题】:How smart is MongoDB?MongoDB有多聪明?
【发布时间】:2011-11-24 00:56:32
【问题描述】:

似乎几乎没有关于如何为 MongoDB 设计数据库的文档。所以我想我先在这里发布我的问题。

假设这个集合(fruits_inventory)作为例子:

{
    "name"      : "Orange",
    "type"      : "citric",
    "available" : 3
}
{
    "name"      : "Apple",
    "type"      : "pome",
    "available" : 0
    "note"      : "Not shipping this month"
}
{
    "name"      : "Pear",
    "type"      : "pome",
    "available" : 2
}

(No indexes set)

1) 字段选择

db.fruits_inventory.findOne({name:"Orange"},{"note":1});

此查询是否会查找仅包含字段 name 且值为 Orange 的文档并在第一次命中时返回,即使它没有设置 note 字段?还是会继续搜索包含note 字段的文档?

2) 具有唯一索引

如果我在name 上设置唯一索引,上一个问题的答案会改变吗?

暂时只有这两个问题。答案将不胜感激。

【问题讨论】:

  • 当你尝试时会发生什么?
  • 我真的不能,因为无论哪种情况,查询都会返回 NULL。我还能如何测试它?
  • 没有关于如何设计的文档:不是真的。但在这里也完全无关紧要。您需要有关查询的文档,并且有据可查。顺便说一句..这些查询没有结果..这能告诉你什么吗?你还能测试什么?
  • > 我真的不能,因为无论哪种情况,查询都会返回 NULL - 你真的应该尝试一下......
  • @BernieHackett:当然我试过了,我使用了 PHP 驱动程序,但我一直得到 NULL,这是有道理的,因为在这两种情况下都找不到我请求的字段。

标签: database-design mongodb


【解决方案1】:

我写了以下脚本:

// sofruit.js
db = db.getSiblingDB('test');

db.fruits_inventory.drop();
db.fruits_inventory.save({
    "name"      : "Orange",
    "type"      : "citric",
    "available" : 3
});
db.fruits_inventory.save({
    "name"      : "Apple",
    "type"      : "pome",
    "available" : 0,
    "note"      : "Not shipping this month"
});
db.fruits_inventory.save({
    "name"      : "Pear",
    "type"      : "pome",
    "available" : 2 
});

var a1 = db.fruits_inventory.findOne({name:"Orange"},{"note":1});

db.fruits_inventory.ensureIndex({name:1}, {unique:true});

var a2 = db.fruits_inventory.findOne({name:"Orange"},{"note":1});

然后我从 mongo shell 运行它并得到:

> load('../mongojs/sofruit.js');
> a1
{ "_id" : ObjectId("4e7d119e9b3e59bf2e0c5199") }
> a2
{ "_id" : ObjectId("4e7d119e9b3e59bf2e0c5199") }  
>

所以,答案是“是”,它会返回第一个命中,即使它没有设置“注释”字段。添加索引不会改变这一点。

【讨论】:

    【解决方案2】:

    可以直接连接mongodb查看一下:

    MongoDB shell version: 2.0.0
    connecting to: test
    > use test
    switched to db test
    > db.fruits_inventory.save({
    ...     "name"      : "Orange",
    ...     "type"      : "citric",
    ...     "available" : 3
    ... });
    > db.fruits_inventory.save({
    ...     "name"      : "Pear",
    ...     "type"      : "pome",
    ...     "available" : 2
    ... })
    > db.fruits_inventory.save({
    ...     "name"      : "Apple",
    ...     "type"      : "pome",
    ...     "available" : 0,
    ...     "note"      : "Not shipping this month"
    ... })
    > db.fruits_inventory.find()
    { "_id" : ObjectId("4e7d0fa5626e0ab7b5074bb0"), "name" : "Orange", "type" : "citric", "available" : 3 }
    { "_id" : ObjectId("4e7d101b626e0ab7b5074bb1"), "name" : "Pear", "type" : "pome", "available" : 2 }
    { "_id" : ObjectId("4e7d1059626e0ab7b5074bb2"), "name" : "Apple", "type" : "pome", "available" : 0, "note" : "Not shipping this month" }
    > db.fruits_inventory.find({name: "Orange"},{"note":1})
    { "_id" : ObjectId("4e7d0fa5626e0ab7b5074bb0") }
    > db.fruits_inventory.ensureIndex({name:1}, {unique:true})
    > db.fruits_inventory.find({name: "Orange"},{"note":1})
    { "_id" : ObjectId("4e7d0fa5626e0ab7b5074bb0") }
    

    因此,在回答您的问题时,当您查询 note 字段时,它只会返回 id 并且拥有唯一索引没有任何区别。

    【讨论】:

    • 不太清楚你的意思是“它只会返回索引”——也许“它会使用索引 [为查询提供服务]”?
    • 谢谢 =) 从 PHP API(我用的就是这个)我只是不断得到 NULL。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-22
    • 2017-05-20
    • 1970-01-01
    • 2021-07-14
    相关资源
    最近更新 更多