Как сравнить элементы массива из того же объекта в MongoDB? - PullRequest
0 голосов
/ 20 марта 2020

У меня есть коллекция документов с данными ниже

[{
_id:ObjectId(),
status:"created",
users:[{
email:"xyz@gmail.com",
role:"admin"
},
{
email:"abc@gmail.com",
role:"admin"
},
{
email:"abc@gmail.com",
role:"user"
}]
},
{
_id:ObjectId(),
status:"created",
users:[{
email:"pqr@gmail.com",
role:"admin"
},
{
email:"abc@gmail.com",
role:"admin"
},
{
email:"pqr@gmail.com",
role:"user"
}]
}]

Я хочу получить количество документов, для которых пользователь с ролью «admin» и «user» создан и статус «создан» ». Теперь я пытаюсь сопоставить идентификатор электронной почты и роль.

db.documents.aggregate([
       {"$match":{
           "status":"created",
    "$expr":{
      "$eq":[
        {"$size":{"$setIntersection":["$users.email_id","$users.email_id"]}},
        0
      ]
    }
  }},
    ])

Можно ли сравнить элементы массива из одного и того же объекта?

1 Ответ

1 голос
/ 21 марта 2020

Я хочу получить количество документов , которые имеют пользователя с ролями "admin" и "user" и статусом «создал». Сейчас я пытаюсь сопоставить идентификатор email и роль.

Вы можете использовать агрегацию или для запроса на поиск следующим образом:

var MATCH_EMAIL = "abc@gmail.com"

db.collection.aggregate( [
  { 
      $match: { 
          $and: [ { status: "created" } , { "users": { $elemMatch: { role: "admin", email: MATCH_EMAIL } } } ],
          "users": { $elemMatch: { role: "user", email: MATCH_EMAIL } } 
      } 
  },
  { 
      $count: "Count" 
  }
] )

// -- or --

db.collection.find( { 
    $and: [ { status: "created" } , { "users": { $elemMatch: { role: "admin", email: MATCH_EMAIL } } } ],
    "users": { $elemMatch: { role: "user", email: MATCH_EMAIL } } 
} ).count()

Обратите внимание, что фильтр запросов одинаков в обоих случаях. Агрегация возвращает результирующий документ, например { "Count" : 1 }, но запрос find возвращает только значение счетчика, например 1.


[РЕДАКТИРОВАТЬ ДОБАВИТЬ]

Обновлен код, чтобы иметь одинаковые адреса электронной почты для пользователей "user" и "admin".

db.collection.aggregate( [
  { 
      $match: { 
          $and: [ { status: "created" } , { "users.role": "admin" } ],
          "users.role": "user"
      } 
  },
  { 
      $unwind: "$users" 
  },
  { 
      $group: { 
          _id: { _id: "$_id", email: "$users.email" },
          roles: { $push: "$users.role" }
      } 
  },
  { 
      $match: { 
          $expr: { $gt: [ { $size: "$roles" }, 1 ] } 
      } 
  },
  { 
      $count: "Count with user+admin roles and same email" 
  }
] )
...