MongoDB基于多个条件从数组中选择

MongoDB基于多个条件从数组中选择,mongodb,mongodb-query,Mongodb,Mongodb Query,我有以下结构(无法更改,即我必须使用): 所以基本上一个模式的字段在一个数组中,它们可以根据1个数组元素中的类型字段(1个模式字段,其值是数组中的1个元素)来识别。对我来说这很奇怪,但我是NoSQL新手,所以这可能没问题。(对于不同的数据,某些字段可能会丢失,并且数据数组中的元素顺序无法保证) 也许这样更容易理解: 表a:type1列| type2列|等等(它们像上面一样存储在数组中) 我的问题是:如何选择多个有条件的字段?我的意思是(在SQL中):从type1=value1和type2=val

我有以下结构(无法更改,即我必须使用):

所以基本上一个模式的字段在一个数组中,它们可以根据1个数组元素中的类型字段(1个模式字段,其值是数组中的1个元素)来识别。对我来说这很奇怪,但我是NoSQL新手,所以这可能没问题。(对于不同的数据,某些字段可能会丢失,并且数据数组中的元素顺序无法保证)

也许这样更容易理解: 表a:type1列| type2列|等等(它们像上面一样存储在数组中)

我的问题是:如何选择多个有条件的字段?我的意思是(在SQL中):从type1=value1和type2=value2的表中选择*

我可以这样选择1:
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()