简体   繁体   中英

Filter on tag-field on children

First of all, I'm not sure I've set this up as it should be, like by the book. I'm from the SQL world and jumped into the NOSQL land.

Ok, so. I have this collection with Projects, and inside the projects I have files as a child-ref. I can populate and all that stuff, works really well. But I want to filter with tags. I have a tags field inside the File collection, an array with strings, pretty straight forward.

What I would like to do is; send a projectId and a string with a spec filter and get the files, belonging to the project and also containing the tag. Oh, and also, populated.

Is this even the right approach with NOSQL/MONGO? I know how I would do it in SQL, with parent_id's and with some joins etc. I've looked into some aggregate but I'm too novice to work it out it seems.

edit, just to show how my collections are built:

Project Collection

[{
  id: 1,
  name: 'Project01',
  files: [
    id: 1,
    id: 2,
    id: 3,
    id: 4,
    id: 5,
    ...
  ]
},
...
]

Files Collection

[{
  id: 1,
  name: 'filename'
  tags: ['a','b']
},{
  id: 2,
  name: 'filename2'
  tags: ['b', 'c']
},{
  id: 3,
  name: 'filename3'
  tags: ['a', 'd', 'e', 'f']
},
...]

The result I'm going for (get all files in project 1 where tags includes 'b'.

{
  id: 1,
  name: 'Project01',
  files: [
    {
      id: 1,
      name: 'filename'
      tags: ['a','b']
    },{
      id: 2,
      name: 'filename2'
      tags: ['b', 'c']
    }
  ]
}

try this $unwind operation in mongodb Collections as per your requirement

[
  {
    _id: 1,
    name: "Project01",
    files: [
      {
        id: 1,
        name: "filename11",
        tags: [
          "a",
          "b"
        ]
      },
      {
        id: 2,
        name: "filename12",
        tags: [
          "b",
          "c"
        ]
      },
      {
        id: 3,
        name: "filename13",
        tags: [
          "a",
          "c"
        ]
      }
    ]
  },
  {
    _id: 2,
    name: "Project02",
    files: [
      {
        id: 1,
        name: "filename21",
        tags: [
          "a",
          "b"
        ]
      },
      {
        id: 2,
        name: "filename22",
        tags: [
          "a",
          "c"
        ]
      },
      {
        id: 3,
        name: "filename23",
        tags: [
          "b",
          "c"
        ]
      }
    ]
  }
]

Method 1: for your project collection

 db.collection.aggregate([
  {
    $match: {
      _id: 1
    }
  },
  {
    $unwind: "$files"
  },
  {
    $match: {
      _id: 1,
      "files.tags": {
        $in: [
          "b"
        ]
      }
    }
  }
])

Method 2 for files collection

   db.collection.aggregate([
  {
    $unwind: "$tags"
  },
  {
    $match: {
      tags: "xyz"
    }
  }
])

Try it here Mongoplayground

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM