在应用程序中,我必须存储和搜索许多半结构化对象(100M +);每个对象都有许多属性,范围从10到10K,一些属性重新出现。通常,一旦存储,对象将不会改变。这些对象可以看作是Python词典。
属性由用户生成,因此我无法预测他们将创建什么。由于架构经常变化,传统的DBMS对于mantain来说会非常痛苦,所以我开始看看MongoDB。乍一看,它看起来很理想,因为我可以将JSON对象转储到其中,并按属性条件搜索它们。
这是我在JSON中的对象流的示例:
{ "my_id": 1,
"number_of_clients": 30,
"height": 450,
"company_code": "fhxA7"
"name":"example"
...
},
{ "my_id": 2,
"wheels": 4,
"height": 450,
"weight": 495,
"type":"Car",
"model": "TestZ6"
...
}, ...
过了一会儿,有数千个不同的领域。在这些对象上,我想运行一些比较并集群类似的对象。查询的示例可以是find all objects that have a field "weight" in range 400-450 and "height" equal to 450
。
实际上,这适用于小样本。将数百万个对象转储到MongoDB后,我可能遇到什么样的可扩展性问题?索引每个不同的领域是否可行?你有类似案例的指针吗?
如果MongoDB不适合这种情况,您会建议您使用哪种其他技术(例如OLAP)?
答案 0 :(得分:1)
除全文索引外,无法索引所有字段。在您的场景中,我不认为全文适用。我的建议是:
不要让用户决定您的数据结构。即使你可以存储它们,使用它们也会很痛苦。您始终可以将它们组织成一个小对象,如:
{
"my_id": 1,
fields: [{
name: "number_of_clients",
value: 30
}, {
name: "height",
value: 450
}, {
name: "company_code",
value: "fhxA7"
}
...
]
}
不是那么直截了当,但是你可以在fields.name
和fields.value
上建立索引:
db.coll_name.ensureIndex({"fields.name": 1});
db.coll_name.ensureIndex({"fields.value": 1});
必要时
db.coll_name.ensureIndex({"fields.name": 1, "fields.value": 1});
您的查询就像找到:
包含'weight'的文件
和
该对象的
value
介于400和450之间
使用$elemMatch执行查询:
db.coll_name.find({
fields: {
$elemMatch: {
name: 'weight',
value: {$gt: 400, $lt: 450}
}
}
});
作为权衡,你必须确保自己没有重复的字段。
这就是我现在想到的一切。希望它有所帮助。