Запрос MongoDB для записей, где значение встречается N раз или более - PullRequest
0 голосов
/ 08 января 2020

Какой запрос MongoDB вернет записи Team, в которых город встречается как минимум дважды в коллекции, и они активны?

Если вы можете ответить только на первую часть, которая также помогает. (Возвращение записей, где город встречается как минимум дважды)

Команды

[
  {teamName: 'Red', city: 'Altanta', active: false},
  {teamName: 'Blue', city: 'NYC', active: true},
  {teamName:'Yellow', city: 'NYC', active: false},
  {teamName:'Green', city: 'NYC', active: true},
  {teamName:'Gray', city: 'Atlanta', active: false},
  {teamName:'Purple', city: 'Atlanta', active: true},
  {teamName:'Black', city: 'Boston', active: false},
  {teamName:'Brown', city: 'Boston', active: true},
  {teamName:'Silver', city: 'Miami', active: false},
  {teamName:'White', city: 'Austin', active: true},
  {teamName:'Gold', city: 'Detroit', active: true},
]

Запрос вернет:

[
  {teamName: 'Blue', city: 'NYC', active: true},
  {teamName:'Green', city: 'NYC', active: true},
  {teamName:'Purple', city: 'Atlanta', active: true},
  {teamName:'Brown', city: 'Boston', active: true},
]

1 Ответ

1 голос
/ 08 января 2020

Пожалуйста, попробуйте это:

Запрос 1:

Teams.aggregate([{ $group: { _id: '$city', count: { $sum: 1 }, data: { $push: '$$ROOT' } } },
{ $match: { count: { $gte: 2 } } },
// Will project data where docs has active:true & data will be [] if none are active
{
    $project: {
        data: {
            $filter: {
                input: '$data',
                as: "item",
                cond: { $eq: ["$$item.active", true] }
            }
        }
    }
},
// Will remove docs where city is repeated but all documents has active:false
{ $match: { data: { $ne: [] } } }]) 

Результат:

/* 1 */
{
    "_id" : "NYC",
    "data" : [ 
        {
            "_id" : ObjectId("5e156407c952870d7dfbb227"),
            "teamName" : "Blue",
            "city" : "NYC",
            "active" : true
        }, 
        {
            "_id" : ObjectId("5e156407c952870d7dfbb229"),
            "teamName" : "Green",
            "city" : "NYC",
            "active" : true
        }
    ]
}

/* 2 */
{
    "_id" : "Atlanta",
    "data" : [ 
        {
            "_id" : ObjectId("5e156407c952870d7dfbb22b"),
            "teamName" : "Purple",
            "city" : "Atlanta",
            "active" : true
        }
    ]
}

/* 3 */
{
    "_id" : "Boston",
    "data" : [ 
        {
            "_id" : ObjectId("5e156407c952870d7dfbb22d"),
            "teamName" : "Brown",
            "city" : "Boston",
            "active" : true
        }
    ]
}

Запрос 2:

Teams.aggregate([
    { $match: { active: true } },
    { $group: { _id: '$city', count: { $sum: 1 }, data: { $push: '$$ROOT' } } },
    { $match: { count: { $gte: 2 } } }, { $project: { count: 0 } }])

Результат:

/* 1 */
{
    "_id" : "NYC",
    "data" : [ 
        {
            "_id" : ObjectId("5e156407c952870d7dfbb227"),
            "teamName" : "Blue",
            "city" : "NYC",
            "active" : true
        }, 
        {
            "_id" : ObjectId("5e156407c952870d7dfbb229"),
            "teamName" : "Green",
            "city" : "NYC",
            "active" : true
        }
    ]
}

Разница между Query1 и Query2 будет такой же, как во втором запросе, который вы ' отфильтровывая active:false, тогда будет меньше документов, и, следовательно, повторяющиеся города будут также выполняться, так как документов будет только меньше (вы можете видеть в результате query1 результат Atlanta & Boston, хотя у них один документ в data).

...