MongoDB基于多个条件从数组中选择
我有以下结构(无法更改,即我必须使用): 所以基本上一个模式的字段在一个数组中,它们可以根据1个数组元素中的类型字段(1个模式字段,其值是数组中的1个元素)来识别。对我来说这很奇怪,但我是NoSQL新手,所以这可能没问题。(对于不同的数据,某些字段可能会丢失,并且数据数组中的元素顺序无法保证) 也许这样更容易理解: 表a:type1列| type2列|等等(它们像上面一样存储在数组中) 我的问题是:如何选择多个有条件的字段?我的意思是(在SQL中):从type1=value1和type2=value2的表中选择* 我可以这样选择1:MongoDB基于多个条件从数组中选择,mongodb,mongodb-query,Mongodb,Mongodb Query,我有以下结构(无法更改,即我必须使用): 所以基本上一个模式的字段在一个数组中,它们可以根据1个数组元素中的类型字段(1个模式字段,其值是数组中的1个元素)来识别。对我来说这很奇怪,但我是NoSQL新手,所以这可能没问题。(对于不同的数据,某些字段可能会丢失,并且数据数组中的元素顺序无法保证) 也许这样更容易理解: 表a:type1列| type2列|等等(它们像上面一样存储在数组中) 我的问题是:如何选择多个有条件的字段?我的意思是(在SQL中):从type1=value1和type2=val
db.a.find({“data.type”:ObjectId(“asd1234=type2”),“data.value”:value2}).pretty()
但是我不知道我怎么能包括type1=value1或者更多的条件。我认为这甚至不好,因为它可以匹配数组中的任何data.value字段,所以这并不意味着类型为type2时,值必须为value2
你将如何解决这个问题
我想对一个条件进行一次查询,然后根据结果进行另一次查询。因此,类似于聚合的管道,但正如我看到的,$match不能在聚合中使用更多次。我想有一种方法可以通过管道传输这些命令,但这很难看。
我错过了什么?还是因为数据的结构,我不得不做这些奇怪的多重查询
我还研究了$filter,但其中的条件也适用于数组的任何元素。(或者我做错了)
谢谢
对不起,如果我不够清楚!请询问,我可以详细说明
(基本上,我基于这个结构()尝试做的是:如果形状是正方形,则过滤蓝色,如果形状是圆形,则过滤红色===如果类型是type1,则值必须是value1,如果类型是type2,则值必须是value2)如果需要检索具有匹配数组元素的文档 多个条件,您必须使用 这将输出元素匹配的整个文档 若要仅输出数组中的第一个匹配元素,可以将其与组合 警告,不要忘记在数据数组外部投影所有其他需要的字段 如果需要输出数组中的所有匹配元素,则必须在聚合$project阶段中使用,如下所示:
db.collection.aggregate([
{
$project: {
data: {
$filter: {
input: "$data",
as: "data",
cond: {
$and: [
{
$eq: [
"$$data.type",
"type1"
]
},
{
$eq: [
"$$data.value",
"value1"
]
}
]
}
}
}
}
}
])
可以这样做:
db.document.find( { $and: [
{ type:ObjectId('abc') },
{ data: { $elemMatch: { type: a, value: DBRef(...)}}},
{ data: { $elemMatch: { type: b, value: "string"}}}
] } ).pretty()
因此,您可以使用$添加任意数量的“条件”,从而可以指定一个元素必须具有类型a和值b,而另一个元素必须具有类型b和值c
如果要仅投影匹配的元素,请使用聚合过滤器:
db.document.aggregate([
{$match: { $and: [
{ type:ObjectId('a') },
{ data: { $elemMatch: { Type: ObjectId("b"), value: DBRef(...)}}},
{ data: { $elemMatch: { Type: ObjectId("c"), value: "abc"}}}
] }
},
{$project: {
metadata: {
$filter: {
input: "$data",
as: "data",
cond: { $or: [
{$eq: [ "$$data.Type", ObjectId("a") ] },
{$eq: [ "$$data.Type", ObjectId("b") ] }]}
}
}
}
}
]).pretty()
这是相当丑陋,所以如果有更好的方法,请张贴它!谢谢 谢谢你的回复!不幸的是,这并不能解决我需要的问题:我还需要补充一点,类型为type2时,值必须为value2(以及其他值)。但这个查询不能做到这一点。所以我需要这样的东西:(type=“type1”和value=“value1”)和(type=“type2”和value=“value2”)。所以,若类型是type1,那个么值就是value1,但若类型是type2,那个么值就是其他东西。所以基于我想查询的排列类型。给出mongodb示例:(product=“abc”和score=10)和(product=“xyz”和score=5)-我需要这样的文档。更多说明:如果所有记录的arrayelements顺序都相同,那么类似的方法应该有效:
db.collection.find({data.firstelement.value=value1,data.secondelement.value=value2,data.thirdelement.value=value3,依此类推}
但不幸的是,一个记录/文档在数据数组中可以有2个元素,另一个可以有8个元素,因此我需要元素的类型来确定它有哪些元素。
db.collection.aggregate([
{
$project: {
data: {
$filter: {
input: "$data",
as: "data",
cond: {
$and: [
{
$eq: [
"$$data.type",
"type1"
]
},
{
$eq: [
"$$data.value",
"value1"
]
}
]
}
}
}
}
}
])
db.document.find( { $and: [
{ type:ObjectId('abc') },
{ data: { $elemMatch: { type: a, value: DBRef(...)}}},
{ data: { $elemMatch: { type: b, value: "string"}}}
] } ).pretty()
db.document.aggregate([
{$match: { $and: [
{ type:ObjectId('a') },
{ data: { $elemMatch: { Type: ObjectId("b"), value: DBRef(...)}}},
{ data: { $elemMatch: { Type: ObjectId("c"), value: "abc"}}}
] }
},
{$project: {
metadata: {
$filter: {
input: "$data",
as: "data",
cond: { $or: [
{$eq: [ "$$data.Type", ObjectId("a") ] },
{$eq: [ "$$data.Type", ObjectId("b") ] }]}
}
}
}
}
]).pretty()