尽管您似乎由于使用嵌套数组时出现更新问题而接近了这种结构,但您实际上只是通过执行其他不受真正支持的操作而导致了另一个问题,那就是没有“通配符”使用最佳标准查询运算符搜索未指定键的概念。
真正搜索此类数据的唯一方法是使用服务器上的 JavaScript 代码来遍历键$where https://docs.mongodb.org/v3.0/reference/operator/query/where/。这显然不是一个好主意,因为它需要蛮力评估而不是使用索引等有用的东西,但可以按如下方式处理:
db.theses.find(function() {
var relations = this.relations;
return Object.keys(relations).some(function(rel) {
return relations[rel].type == "interpretation";
});
))
虽然这将从集合中返回包含所需嵌套值的对象,但它必须检查集合中的每个对象才能进行评估。这就是为什么这样的评估实际上应该只在与可以直接使用索引而不是作为集合中对象的硬值的东西配对时使用。
更好的解决方案仍然是考虑重构数据以利用搜索中的索引。如果需要更新“收视率”信息,那么基本上“压扁”将每个“评级”元素视为唯一数组数据的结构:
{
"_id": "aeokejXMwGKvWzF5L",
"text": "test",
"relationsRatings": [
{
"relationId": "cF6iKAkDJg5eQGsgb",
"type": "interpretation",
"originId": "uFEjssN2RgcrgiTjh",
"ratingId": 1,
"ratingScore": 5
},
{
"relationId": "cF6iKAkDJg5eQGsgb",
"type": "interpretation",
"originId": "uFEjssN2RgcrgiTjh",
"ratingId": 2,
"ratingScore": 6
}
]
}
现在搜索当然非常简单:
db.theses.find({ "relationsRatings.type": "interpretation" })
当然还有位置性的$ https://docs.mongodb.org/v3.0/reference/operator/update/positional/运算符现在可以与更扁平的结构一起使用:
db.theses.update(
{ "relationsRatings.ratingId": 1 },
{ "$set": { "relationsRatings.$.ratingScore": 7 } }
)
当然,这意味着每个“评级”值的“相关”数据的重复,但这通常是按匹配位置更新的成本,因为这仅是单层数组嵌套所支持的。
因此,您可以强制逻辑与您的结构方式相匹配,但这不是一个好主意,并且会导致性能问题。然而,如果您在这里的主要需求是更新“评级”信息,而不仅仅是附加到内部列表,那么更扁平的结构将带来更大的好处,当然搜索速度也会更快。