我想知道是否有办法在mongo中
$match
在字典列表中找到确切的字典
我有包含此字段的文档
{
_id: ObjectId("6644d9860e3b38f3dd724241"),
fields: {
allowed_urls: [
{
url: "/my_url/",
method: "POST"
},
{
url: "/my_url/",
method: "GET"
}
]
}
}
我正在像这样过滤我的文档,以找到文档具有带有过滤器参数的字典的确切文档
[{'$match': {'fields.allowed_urls.url': '/my_url/', 'fields.allowed_urls.method': 'POST'}}]
但是由于某种原因,如果文档看起来像这样
{
_id: ObjectId("6644d9860e3b38f3dd724241"),
fields: {
allowed_urls: [
{
url: "/another_url/",
method: "POST"
},
{
url: "/my_url/",
method: "GET"
}
]
}
}
Mongo 也会找到他,因为这个文档有 my_url 和 POST,但我想在 1 个字典中找到只有精确参数的文档。我试图做类似
fields.allowed_urls.$.method
的事情,但这没有帮助
发生这种情况的原因是每个字段检查都可以与列表中的any元素匹配。所以这个查询
db.collection.find({
"fields.allowed_urls.url": "/my_url/",
"fields.allowed_urls.method": "POST"
})
将匹配具有以下内容的文档:
"fields.allowed_urls.url": "/my_url/"
在任何元素或子文档中,并且"fields.allowed_urls.method": "POST"
在任何元素或子文档中。因此
POST
与数组中的第一个元素匹配,而 "/my_url/"
与数组中的第二个元素匹配。
要针对数组中的单个元素和整个元素的精确匹配进行此操作,请将搜索字段放在同一父键/字段下:
db.collection.find({
"fields.allowed_urls": {
"url": "/my_url/",
"method": "POST"
}
})
Mongo Playground - 请注意带有额外字段
other: "only with elemMatch"
的第三个文档如何不会出现在结果中,即使它具有 POST
和 my_url
。
如果您想对对象进行部分匹配,但仍在单个元素内,例如检查同一子对象的 3 个字段中的 2 个,请使用
$elemMatch
:
db.collection.find({
"fields.allowed_urls": {
$elemMatch: {
"url": "/my_url/",
"method": "POST"
}
}
})
Mongo Playground - 这个确实返回带有额外字段的第三个文档。