我正在尝试将键值数据存储在MongoDb中。 键可以是任何字符串,在存储之前我一无所知,值可以是任何类型(整数,字符串,数组)。我想在这样的键和值上建立索引。
我正在(<Multikey Index)上查看我的键值数组,但是看起来它无法涵盖对数组字段的查询。
是否可以在mongoDb中的自定义键和值上建立索引,并使用$ exists和$ eq和$ gte,$ lte等操作进行查询,$ and,$ or,$ in没有COLLSCAN但通过IXSCAN阶段? 或者也许我需要另一个Db?
答案 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 } })