MongoDB获取数组值匹配的所有文档
我的文件结构如下:MongoDB获取数组值匹配的所有文档,mongodb,Mongodb,我的文件结构如下: { "input": { "fields": [ { "name": "last_name_hebrew", "text": "test1", }, ], }, "output": { "fie
{
"input": {
"fields": [
{
"name": "last_name_hebrew",
"text": "test1",
},
],
},
"output": {
"fields": [
{
"name": "last_name_hebrew",
"text": "test1"
},
],
},
},
我想获取所有文档,其中字段的对象的名称为valuelast\u name\u hebrew
,与输出的值相同
例如,在给定的结构中,它将返回此文档,因为input.fields.name
是last\u name\u hebrew
,而text
等于output
中的text
注意:我不能保证输入
或输出
中的字段
数组将在数组中包含name:last\u name\u hebrew
我怎样才能做到
这是我第一次尝试强制数组中的文档名为last\u name\u hebrew
:
db.collection.find({
"input.fields": {
$elemMatch: {
"name": "last_name_hebrew"
}
},
"output.fields": {
$elemMatch: {
"name": "last_name_hebrew"
}
},
})
但是现在我需要比较文本
值。您必须使用聚合管道来实现这一点,有几种方法可以实现,下面是一个示例:
db.collection.aggregate([
{
$match: {
$expr: {
$gt: [
{
$size: {
$filter: {
input: "$input.fields",
as: "inputField",
cond: {
$and: [
{
$eq: [
"$$inputField.name",
"last_name_hebrew"
]
},
{
"$setIsSubset": [
[
"$$inputField.text"
],
"$output.fields.text"
]
}
]
}
}
}
},
0
]
}
}
}
])
需要注意的一点是,此查询对输出.fields.name
没有限制(因为它不是必需的),如果确实需要名称匹配,则可以在$setIsSubset
操作符中删除.text
字段。
- 您使用
$elemMatch
的前2个条件是正确的
- 添加表达式匹配,首先使用
$filter
从input
中查找具有姓氏\u希伯来语
名称的匹配元素,然后使用$arrayElemAt
从过滤结果中获取第一个元素,对输出
字段执行相同的过程,然后使用$eq
匹配两个对象
第二个选项:如果您想使用更具体的方法来匹配精确的两个字段name
和text
,这两个字段只需添加$let
操作符即可从过滤器返回字段
db.collection.find({
"input.fields": { $elemMatch: { "name": "last_name_hebrew" } },
"output.fields": { $elemMatch: { "name": "last_name_hebrew" } },
$expr: {
$eq: [
{
$let: {
vars: {
input: {
$arrayElemAt: [
{
$filter: {
input: "$input.fields",
cond: { $eq: ["$$this.name", "last_name_hebrew"] }
}
},
0
]
}
},
in: { name: "$$input.name", text: "$$input.text" }
}
},
{
$let: {
vars: {
output: {
$arrayElemAt: [
{
$filter: {
input: "$output.fields",
cond: { $eq: ["$$this.name", "last_name_hebrew"] }
}
},
0
]
}
},
in: { name: "$$output.name", text: "$$output.text" }
}
}
]
}
})
第三个选项:为了更具体地检查循环中的两个字段
- 首先使用$filter在输入字段中按名称筛选匹配的元素
- 通过以上过滤器将导致另一个过滤器
- 筛选以匹配输出字段中的名称和文本字段,如果其不是[]空,则返回筛选结果
$ne
检查返回结果是否不为[]空
输出.字段.名称可以是什么吗?听起来这不是一个约束。@TomSlabbaert是的,它可以是任何东西。我正在寻找那些name
值为last\u name\u hebrew
的人,我打开了你的游乐场链接,你的查询似乎是错误的,因为输入的名称是last\u name\u hebrew
和test1
文本,但你的输出
字段中没有任何匹配项。那里匹配的名称是last\u name\u hebrew
,但是文本是test21
,它不等于test1
,首先您可以在那里更改代码,其次输出
和输入
是数组,因为你没有提供关于有多少个项目可以在那里的扩展信息,所以我假设它可以超过1个。你是回答的人。如果你的解决方案是错误的,你需要改变它。您是否知道您的解决方案是错误的?正如评论中所述-此解决方案不符合我的要求。。
db.collection.find({
"input.fields": { $elemMatch: { "name": "last_name_hebrew" } },
"output.fields": { $elemMatch: { "name": "last_name_hebrew" } },
$expr: {
$eq: [
{
$let: {
vars: {
input: {
$arrayElemAt: [
{
$filter: {
input: "$input.fields",
cond: { $eq: ["$$this.name", "last_name_hebrew"] }
}
},
0
]
}
},
in: { name: "$$input.name", text: "$$input.text" }
}
},
{
$let: {
vars: {
output: {
$arrayElemAt: [
{
$filter: {
input: "$output.fields",
cond: { $eq: ["$$this.name", "last_name_hebrew"] }
}
},
0
]
}
},
in: { name: "$$output.name", text: "$$output.text" }
}
}
]
}
})
db.collection.find({
"input.fields": { $elemMatch: { "name": "last_name_hebrew" } },
"output.fields": { $elemMatch: { "name": "last_name_hebrew" } },
$expr: {
$ne: [
{
$filter: {
input: {
$filter: {
input: "$input.fields",
cond: { $eq: ["$$this.name", "last_name_hebrew"] }
}
},
as: "i",
cond: {
$ne: [
{
$filter: {
input: "$output.fields",
cond: {
$and: [
{ $eq: ["$$this.name", "$$i.name"] },
{ $eq: ["$$this.text", "$$i.text"] }
]
}
}
},
[]
]
}
}
},
[]
]
}
})