我的文件结构如下:
{
"input": {
"fields": [
{
"name": "last_name_hebrew",
"text": "test1",
},
],
},
"output": {
"fields": [
{
"name": "last_name_hebrew",
"text": "test1"
},
],
},
},我希望获得所有文档,其中字段的对象具有值last_name_hebrew的名称,与output.fields的text值相同。
例如,在给定的结构中,它将返回这个文档,因为input.fields.name是last_name_hebrew,text等于output中的text。
注意,我不能保证fields数组在input或output中都会有name: last_name_hebrew在数组中。
我怎样才能做到呢?
这是我第一次尝试使用name of last_name_hebrew强制数组拥有文档。
db.collection.find({
"input.fields": {
$elemMatch: {
"name": "last_name_hebrew"
}
},
"output.fields": {
$elemMatch: {
"name": "last_name_hebrew"
}
},
})但是现在我需要比较text值。
发布于 2021-04-04 12:47:01
$elemMatch的第一个2条件是正确的last_name_hebrew从input查找具有$filter名称的匹配元素,然后使用$arrayElemAt从筛选结果中获取第一个元素,对output字段进行相同的处理,然后使用$eq匹配两个对象。db.collection.find({
"input.fields": { $elemMatch: { "name": "last_name_hebrew" } },
"output.fields": { $elemMatch: { "name": "last_name_hebrew" } },
$expr: {
$eq: [
{
$arrayElemAt: [
{
$filter: {
input: "$input.fields",
cond: { $eq: ["$$this.name", "last_name_hebrew"] }
}
},
0
]
},
{
$arrayElemAt: [
{
$filter: {
input: "$output.fields",
cond: { $eq: ["$$this.name", "last_name_hebrew"] }
}
},
0
]
}
]
}
});第二个选项:如果您想要更具体地匹配确切的2个字段,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" }
}
}
]
}
})第三个选项:为了更具体地检查循环中的两个字段,
$ne不为[]空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"] }
]
}
}
},
[]
]
}
}
},
[]
]
}
})发布于 2021-03-25 15:56:02
您必须使用聚合管道来实现这一点,有几种方法可以这样做,下面是一个示例:
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
]
}
}
}
])蒙戈游乐场需要注意的一点是,对于这个查询,对output.fields.name没有任何限制(因为它不是必需的),如果您确实要求名称匹配,那么您可以在$setIsSubset操作符中删除.text字段。
https://stackoverflow.com/questions/66801727
复制相似问题