在这样的文档中:
[
{
a: "",
b: 1,
"createdAccounts": {
"[email protected]": {
"id": ["a", "b", "c"]
}
}
}
]
我正在查询电子邮件:
const email = "[email protected]"
let account = await db.collection("users").aggregate(
[
{
"$project": {
"createdAccounts": {
"$objectToArray": "$createdAccounts"
}
}
},
{
"$match": {
"createdAccounts.k": email
}
},
{
"$project": {
"createdAccounts": {
"$arrayToObject": "$createdAccounts"
}
}
}
]).toArray().then(results =>
{
const document = results[0];
if (document && document.createdAccounts)
return document.createdAccounts[email];
return null;
})
我想知道是否有“更好的方法”来查询电子邮件,我使用聚合,因为搜索的键可以在其路径中包含一个点(
.
)
在这种情况下,这个:
const email = "[email protected]"
let account = await db.collection("users").findOne({ "createdAccounts.email": email });
不起作用。
使用我得到的聚合查询作为响应:
"[email protected]": {
"id": ["a", "b", "c"]
}
假设我需要修改
id
数组,因为它的内部包含一个点 (.
)
我找不到如何更新它。
另外,update方法会连接数组还是覆盖数组?
首先,您确实应该为此使用属性模式。 Mongo 不能很好地处理“未知键”,这与 JS(和 Python)不同,您可以在 JS(和 Python)中迭代键和值。
此管道将在
id
字段中附加一个元素,用于匹配的电子邮件。
db.users.aggregate([
{
"$project": {
"createdAccounts": {
"$objectToArray": "$createdAccounts"
}
}
},
{
"$match": {
// replace with the `email` you want to match
"createdAccounts.k": "[email protected]"
}
},
{
"$set": {
"createdAccounts.v.id": {
"$concatArrays": [
// unclear why I need this "first" but the
// concat produces an extra array if I don't
{ "$first": "$createdAccounts.v.id" },
["X"] // <-- put the element you want to add
]
}
}
},
{
"$set": {
"createdAccounts": {
"$arrayToObject": "$createdAccounts"
}
}
},
{
"$merge": {
"into": "collection",
"on": "_id",
"whenMatched": "merge",
"whenNotMatched": "discard"
}
}
])
请注意,在 Mongo Playground 中,它只会根据管道结果显示文档。合并结果可以通过查看集合中更新的文档来看到。
结果:
{
"_id": 1,
"a": "",
"b": 1,
"createdAccounts": {
"[email protected]": {
"id": [
"a",
"b",
"c",
"X"
]
}
}
}