我认为在mongodb文档中嵌入数据至少有两种方法.在一个简化的例子中,我们可以有如下内容:

{
    'name' : 'bill',
    'lines': {
       'idk73716': {'name': 'Line A'},
       'idk51232': {'name': 'Line B'},
       'idk23321': {'name': 'Line C'}
    }
}

作为一个数组:

{
    'name' : 'bill',
    'lines': [
       {'id': 'idk73716', 'name': 'Line A'},
       {'id': 'idk51232', 'name': 'Line B'},
       {'id': 'idk23321', 'name': 'Line C'}
    ]
}

正如您在本用例中看到的,保持每一行的id是很重要的.

我想知道这两种模式之间是否有利弊.尤其是在使用索引时,我觉得第二种可能更容易使用,因为可以在"行"上创建索引.id"甚至"行.name'搜索所有文档中的id或名称.在第一个示例中,我没有找到任何有效的解决方案来索引ID('idk73716'等等).

如果您有这样的用例,通常会倾向于使用第二种方法吗?

推荐答案

在第一种方法中,由于id用作键,所以不能为id字段编制索引.它有点像键值字典.如果您拥有一组已知的ID(当然数量较少),这种方法非常有用.假设在第一个示例中,前面的id是众所周知的,

>>db.your_colleection.find()
 { "_id" : ObjectId("4ebbb6f974235464de49c3a5"), "name" : "bill", 
  "lines" : { 
             "idk73716" : { "name" : "Line A" },
             "idk51232" : { "name" : "Line B" } ,
             "idk23321":  { "name" : "Line C" }
            } 
  }

因此,要找到id字段idk73716的值,可以通过

 db.your_colleection.find({},{'lines.idk73716':1})
 { "_id" : ObjectId("4ebbb6f974235464de49c3a5"), "lines" : { "idk73716" : { "name" : "Line A" } } }

空的{}表示查询,第二部分{'lines.idk73716':1}是查询 Select 器.

having ids as keys having an advantage of picking the particular field alone.尽管{'lines.idk73716':1}是一个字段 Select 器,但在这里它充当查询和 Select 器.但这不能在你的第二种方法中实现.假设第二个系列是这样的

> db.second_collection.find()
{ "_id" : ObjectId("4ebbb9c174235464de49c3a6"), "name" : "bill", "lines" : [
    {
        "id" : "idk73716",
        "name" : "Line A"
    },
    {
        "id" : "idk51232",
        "name" : "Line B"
    },
    {
        "id" : "idk23321",
        "name" : "Line C"
    }
] }
> 

您为字段id编制了索引,所以如果您想按id进行查询

> db.second_collection.find({'lines.id' : 'idk73716' })

{ "_id" : ObjectId("4ebbb9c174235464de49c3a6"), "name" : "bill", "lines" : [
    {
        "id" : "idk73716",
        "name" : "Line A"
    },
    {
        "id" : "idk51232",
        "name" : "Line B"
    },
    {
        "id" : "idk23321",
        "name" : "Line C"
    }
] }
> 

通过查看上述输出,可以看出无法单独 Select 匹配的子(嵌入)文档,但在第一种方法中是可能的.这是mongodb的默认行为.

看见

db.second_collection.find({'lines.id' : 'idk73716' },{'lines':1})

将获取所有行,而不仅仅是idk73716

{ "_id" : ObjectId("4ebbb9c174235464de49c3a6"), "lines" : [
    {
        "id" : "idk73716",
        "name" : "Line A"
    },
    {
        "id" : "idk51232",
        "name" : "Line B"
    },
    {
        "id" : "idk23321",
        "name" : "Line C"
    }
] }

希望这有帮助

EDIT

感谢@Gates VP的指点

db.your_collection.find({'lines.idk73716':{$exists:true}}).如果你

我们仍然可以使用$exists来查询id,但它将不可索引

Mongodb相关问答推荐

MongoDB聚合:将文档列表转换为列表

MongoDB.ArrayFilters出错:在路径中找不到标识符';elem';的数组筛选器

MongoDB$unionWith,如何 Select 特定文档

MongoDB MQL,将列表一分为二,仅获取唯一值

在MongoDB中获取所有帖子时如何获取相关用户信息

如何使用聚合管道查找未销售但存在于产品详细信息集合中的产品的ID

mongoose正在抛出Schema的错误has';t已在next.js中注册

如何向所有文档添加一个字段,其中前 100 个文档的值为 1,接下来的 100 个文档的值为 2,依此类推?

Spring Data + MongoDB GridFS 可以通过 Repository 访问吗?

Mongo 删除最后的文件

你如何在 Kubernetes 上设置 Mongo 副本集?

使用 MongoDB 进行分页

在mongodb中实现分页

MongoDB:自动生成的 ID 为零

MongoDB - 投影一个并不总是存在的字段

MongoDB 数据库,相当于 SELECT column1, column2 FROM tbl

一起使用 MongoDB 和 Neo4j

spring 数据MongoDB.生成id的错误

Mongoose 为所有嵌套对象添加 _id

mongoose — 判断 ObjectId 是否存在于数组中