【问题标题】:Can mongoDB compare field names instead of field values?mongoDB可以比较字段名而不是字段值吗?
【发布时间】:2013-04-17 13:43:24
【问题描述】:

在定义要返回的字段(collection.find(q, fields)) 时,mongoDB 是否(如何)支持比较字段名称(而不是值)?

例如根据名称选择一系列字段,而不考虑其值。

假设文档中有以下字段(无论值可能是什么):

fieldA000 fieldA001 fieldA002 fieldB000 fieldB001 fieldC000 ...

我想限制任何匹配fieldA000 to fieldA999(无需明确定义任何字段名称)或fieldA.*(reg ex)或类似名称的字段的返回字段。

P.S.:我目前正在评估是否可以使用 mongoDB 代替 Cassandra,因为 Cassandra 以非常易于使用的方式提供了 column-range/slice-select。

【问题讨论】:

    标签: mongodb mongo-java


    【解决方案1】:

    Mongo 没有办法在键名上使用正则表达式来匹配文档。

    但是,您可以使用$where 执行此操作,它允许您使用执行 JavaScript 来选择每个文档。 $where 的缺点是它不能利用索引,因此它需要反序列化集合中的每个文档,这对于大多数应用程序来说太慢了。

    在 Mongo 中执行此操作的另一种方法是使用 $exists 和 $or,但它需要明确的键名。

    这样的模式对于这种类型的查询会更有效,并且还有助于使用$在服务器上进行切片:

    {
        dataFields: [
            { id: 'A000', value: 'whatevs' },
            { id: 'A001', value: 'whatevs' },
            { id: 'A002', value: 'whatevs' },
            { id: 'B000', value: 'whatevs' },
            { id: 'B001', value: 'whatevs' },
            { id: 'C000', value: 'whatevs' },
        ]
    }
    

    或:

    {
        dataFields: [
            { lettter: 'A', number: 0, value: 'whatevs' },
            { lettter: 'A', number: 1, value: 'whatevs' },
            { lettter: 'A', number: 2, value: 'whatevs' },
            { lettter: 'B', number: 0, value: 'whatevs' },
            { lettter: 'B', number: 1, value: 'whatevs' },
            { lettter: 'C', number: 0, value: 'whatevs' },
        ]
    }
    

    【讨论】:

    • 顺便说一句:通过在字段字母和数据字段数组的数字上创建索引可以大大提高循环速度。
    • 非常感谢。我有点希望我不需要生成不同的结构(与我们在 Cassandra 上使用的结构不同)。
    【解决方案2】:

    MongoDB 允许您在每个查询操作上提供一个投影,它指定要返回的字段。

    您不能基于模式包含或排除字段。您可以做的是标记要包含的字段:

    db.foo.find({}, {'A000': 1, 'A001': 1, 'B000': 1})

    (此查询将返回 _id、A000、A001 和 B000 字段)。

    或者,标记要排除的特定字段:

    db.foo.find({}, {'B000': 0})

    (此查询将返回除 B000 以外的所有字段)。

    更多信息请参见this link。

    一般来说,使用这样的投影来模拟列切片对于文档数据库来说并不是一个很好的用例——而数据不会从数据库服务器返回到客户端(节省网络和客户端解析开销),它仍然会从磁盘读取(除非可以使用覆盖索引来返回所有字段),并且必须解析文档以确定要排除哪些部分。

    【讨论】:

    • 这与问题有什么关系?
    • @Sammaye:“并且我想限制与 fieldA000 到 fieldA999 匹配的任何字段名称的返回字段” - 我将其视为有关如何限制与结果一起返回的字段的问题,而不是关于如何过滤返回的文档。你不同意吗?
    • 确实它确实投射了一定数量,但是他不确定有多少字段,因此他希望使用正则表达式来投射所有匹配范围的字段,他的问题也可能会被简化。换句话说,这是行不通的。
    • 投影也可以使用索引
    • 投影可以(也将)使用索引。但是除非索引完全覆盖投影,否则 IO 不会被保存——这在返回大量字段的情况下不太可能。我已将其添加到答案中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 2020-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多