【发布时间】:2012-06-17 20:55:08
【问题描述】:
在 Java 中,我有一个看起来像这样的对象:
class MyDoc {
ObjectId docId;
Map<String, String> someProps = new HashMap<String,String>();
}
当持久化到 MongoDB 时会生成以下文档:
{
"_id" : ObjectId("4fb538eb5e9e7b17b211d5d3"),
"someProps" : {
"4fda4993eb14ea4a4a149c04" : "PROCESSED",
"4f56a5c4b6f621f092b00525" : "PROCESSED",
"4fd95a2a0baaefd1837fe504" : "TODO"
}
}
我需要查询如下。
DBObject queryObj =
new BasicDBObject("someProps.4fda4993eb14ea4a4a149c04","PROCESSED");
DBObject explain =
getCollection().find(queryObj).hint("props_indx").explain();
这应该是找到我的 MyDoc 文档,这些文档有一个 someProps,键为“4fda4993eb14ea4a4a149c04”,值为“Processed”
我在集合中存储了数百万个 MyDoc 文档,因此我需要对 someProps 嵌入对象的键进行有效索引。
事先不知道地图的键(它们是动态生成的,它们不是一组固定的键),因此我无法为每个 someProps 键创建一个索引。 (至少我不认为如果我错了我可以纠正我)
我尝试直接在 someProps 上创建索引,但查询需要很长时间。
如何索引 someProps Map 键? 我需要不同的文档结构吗?
重要提示:
1 . someProps 中只能有一个元素具有相同的键。例如:
{
"_id" : ObjectId("4fb538eb5e9e7b17b211d5d3"),
"someProps" : {
"4fda4993eb14ea4a4a149c04" : "PROCESSED",
"4f56a5c4b6f621f092b00525" : "PROCESSED",
"4f56a5c4b6f621f092b00525" : "TODO"
}
}
将无效,因为 4f56a5c4b6f621f092b00525 在地图中找不到两次(因此首先使用地图)
2 。我还需要有效地更新 someProps,只更改值(例如:将“4fda4993eb14ea4a4a149c04”:“PROCESSED”更改为“4fda4993eb14ea4a4a149c04”:“CANCELLED”)
我有什么选择?
谢谢。
【问题讨论】:
-
看起来最好将这些设置移动到单独的文档中。
-
@Sergio : 你的意思是把文档 somProps 放在一个单独的集合中吗?
-
是的,我会将来自
someProps的每个条目制作成一个单独的文档。 -
将它们放在另一个集合中会解决索引未知键名的问题吗?恐怕我没看到。
-
是的,它会变成这样:
{k: '4fda4993eb14ea4a4a149c04', v: 'PROCESSED'}。这是完全可索引的。