使用索引查询MongoDb的自定义键和值

时间:2018-10-03 16:55:27

标签: mongodb mongodb-query aggregation-framework key-value key-value-store

我正在尝试将键值数据存储在MongoDb中。 可以是任何字符串,在存储之前我一无所知,可以是任何类型(整数,字符串,数组)。我想在这样的上建立索引。

我正在(<Multikey Index)上查看我的键值数组,但是看起来它无法涵盖对数组字段的查询。

是否可以在mongoDb中的自定义上建立索引,并使用$ exists和$ eq和$ gte,$ lte等操作进行查询,$ and,$ or,$ in没有COLLSCAN但通过IXSCAN阶段? 或者也许我需要另一个Db?

2 个答案:

答案 0 :(得分:1)

如果您的for (Map.Entry<String, ArrayList> data : records) { ArrayList list = (ArrayList) data.getValue(); for (int i = 0; i < list.size(); i++) { if (list.get(i).equals(recordId)) { // do something } } } 可以是任意值,那么这是不可能的。最好的选择是在其他已知字段上创建索引,以限制初始结果,从而将不可避免的集合扫描的影响减小到最小。

答案 1 :(得分:1)

我可能误解了您的问题,但是我认为这正是MongoDB的优势所在-处理不同形状的文档和数据类型。

因此,假设您必须遵循以下两个文档:

db.test.insertMany([
    {
        key: "test",
        value: [ "some array", 1 ]
    },
    {
        key: 12.7,
        values: "foo"
    }
])

,您将创建一个compound索引,如下所示:

db.test.createIndex({
    "key": 1,
    "value": 1
})

然后以下查询将使用该索引:

db.test.find({ "key": "test", "value": 1 })

和更复杂的查询将执行相同的操作:

db.test.find({ "key": { $exists: true }, "value": { gt: 0 } })

您可以通过在上述查询的末尾添加.explain()来验证这一点。

根据您的评论进行更新:

您不需要聚合框架。您可以简单地执行以下操作:

db.test.distinct("user_id", { "key": { $exists: true } })

此查询将使用以上索引。此外,可以通过更改索引定义以使其包含"user_id"字段来使速度更快,如下所示:

db.test.createIndex({
    "key" : 1.0,
    "value" : 1.0,
    "user_id" : 1
})

同样,可以通过运行以下查询来验证:

db.test.explain().distinct("user_id", { "key": { $exists: true } })