Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
250 views
in Technique[技术] by (71.8m points)

aggregation framework - Display the conditionnal size of an array with the others fields of a mongodb document

I have a collection of fridges and I would like to have some fields from each fridge matching a condition plus the 'conditionnal size' of the items in this fridge.

This is an example of my DB :

db={
  "fridges": [
    {
      _id: 1,
      items: [
        {
          itemId: 1,
          name:"beer"
        },
        {
          itemId: 2,
          name: "chicken"
        }
      ],
      brand:"Bosch",
      size:195,
      cooler:true,
      color:"grey"
    },
    
    {
      _id: 2,
      items: [
        {
          itemId: 1,
          name:"beer"
        },
        {
          itemId: 2,
          name: "chicken"
        },
        {
          itemId: 3,
          name: "lettuce"
        }
      ],
      brand:"Electrolux",
      size:200,
      cooler:true,
      color:"white"
    },
  ]
}

I want to get fridges with these mutuals conditions ('and' condition):

  • brand is $in ["Bosch","Samsung"]
  • color is $in ["grey","white"]

In addition : The number of items with a name $in ["beer","lettuce"]

And finally : Removing some fields like the size and items of the result.

In our example, the excepted output would be :

{
  _id:1
  itemsNumber:1,
  brand:"Bosch",
  cooler:true,
  color:"grey"
}

Explanations : We removed the field items and size, itemsNumber counts the number of beers and lettuce from items array. And we only keep the first fridge its brand is Bosch and it's grey.

This what I have so far :

db.fridges.aggregate([
  {
    "$match": {
      $and: [
        {
          "brand": {
            $in: [
              "Bosch",
              "Samsung"
            ]
          }
        },
        {
          "color": {
            $in: [
              "grey",
              "white"
            ]
          }
        }
      ]
    }
  },
  {
    "$project": {
      "itemsNumber": {
        $size: "$items" // This is not good
      },
      brand: 1,
      cooler: 1,
      color: 1
    }
  }
])

Which returns me :

[
  {
    "_id": 1,
    "brand": "Bosch",
    "color": "grey",
    "cooler": true,
    "itemsNumber": 2
  }
]

Counting the items matching with either beer or lettuce is my main problem. This is an executable example.

Thanks in advance !

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I found out how to make it work. Thank you @joe for suggesting to use filter this was indeed the solution.

Here is the complete query :

db.fridges.aggregate([
  {
    $match: {
      $and: [
        {
          "brand": {
            $in: [
              "Bosch",
              "Samsung"
            ]
          }
        },
        {
          "color": {
            $in: [
              "grey",
              "white"
            ]
          }
        }
      ]
    }
  },
  {
    $project: {
      "itemsNumber": {
        "$filter": {
          "input": "$items",
          "as": "item",
          "cond": {
            $in: [
              "$$item.name",
              [
                "beer",
                "lettuce"
              ]
            ]
          }
        }
      },
      brand: 1,
      cooler: 1,
      color: 1
    }
  }
])

Runnable example.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...