Запрос массива вложенных документов с фильтром и возврат оригиналов документов с помощью mongoose - PullRequest
1 голос
/ 25 сентября 2019

Я использую mongoose и имею следующую структуру документов:

{
  user: {
    comments: [
      { title: "mpla", active: true },
      { title: "mpla", active: false }
    ]
  }
}
...

Как мне вернуть все мои документы, но только активные комментарии в массиве комментариев.

Ответы [ 2 ]

1 голос
/ 25 сентября 2019

В общем случае здесь, где основные документы могут иметь другие поля, отличные от user и user doc , могут иметь и другие поля:

Образцы документов:

[
  {
    user: {
      comments: [
        { title: "mpla", active: true },
        { title: "mpla", active: false }
      ],
      name: "abc",
      gender: "male",
      createdDate: new Date("2019-04-01"),
      modifiedDate: new Date("2019-08-24")
    },
    story: {
      name: "a mocking bird",
      year: 1994,
      cost: "$5"
    }
  },
  {
    user: {
      comments: [
        { title: "nope", active: true },
        { title: "hello", active: true }
      ],
      name: "pqr",
      gender: "female",
      createdDate: new Date("2019-05-01"),
      modifiedDate: new Date("2019-09-24")
    },
    story: {
      name: "a kite runner",
      year: 2005,
      cost: "$2"
    }
  }
]

Теперь здесь должны быть возвращены все поля с документами, но массив комментариев должен содержать active=true только документы.

Запрос агрегации с $ filter и $ project :

db.collection.aggregate([
  {
    $project: {
      _id: 1,
      story: 1,
      user: {
        name: 1,
        gender: 1,
        createdDate: 1,
        modifiedDate: 1,
        comments: {
          $filter: {
            input: "$user.comments",
            as: "comment",
            cond: { $eq: ["$$comment.active", true] }
          }
        }
      }
    }
  }
]).pretty();

Выходные документы:

{
    "_id" : ObjectId("5d8bb8c66926e92a334275d4"),
    "user" : {
        "name" : "abc",
        "gender" : "male",
        "createdDate" : ISODate("2019-04-01T00:00:00Z"),
        "modifiedDate" : ISODate("2019-08-24T00:00:00Z"),
        "comments" : [
            {
                "title" : "mpla",
                "active" : true
            }
        ]
    },
    "story" : {
        "name" : "a mocking bird",
        "year" : 1994,
        "cost" : "$5"
    }
},
{
    "_id" : ObjectId("5d8bb8c66926e92a334275d5"),
    "user" : {
        "name" : "pqr",
        "gender" : "female",
        "createdDate" : ISODate("2019-05-01T00:00:00Z"),
        "modifiedDate" : ISODate("2019-09-24T00:00:00Z"),
        "comments" : [
            {
                "title" : "nope",
                "active" : true
            },
            {
                "title" : "hello",
                "active" : true
            }
        ]
    },
    "story" : {
        "name" : "a kite runner",
        "year" : 2005,
        "cost" : "$2"
    }
}
1 голос
/ 25 сентября 2019

Вам нужно будет использовать агрегацию mongodb, поэтому запрос будет:

db.collectionName.aggregate(
 {
   $unwind:  $user.comments
 }
) 

Это приведет к деконструкции массива комментариев и будет включать другие поля, такие как идентификатор, включенный в каждый документ.Например, предположим, что ваш документ был:

{ "_id": 1, "user" : 
   { "comments": 
     [ { "title": "mpla", "active" : true }, { "title": "mpla", "active" : false }  }]
    }
}

Как только мы выполним указанный выше запрос, он приведет к следующим документам:

{ "_id": 1, "user" : 
   { "comments": { "title": "mpla", "active" : true }  
   }
 }
}

{ "_id": 1, "user" : 
   { "comments": { "title": "mpla", "active" : false }   
   }
 }
}

Как вы можете видеть, у нас есть два отдельныхдокументы теперь вы можете запросить их, используя оператор $ match, и сгруппировать их обратно в массив, используя оператор $ group.Надеюсь, что это отвечает на ваш вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...