随机文档由两个或多个字段聚合

时间:2017-12-09 10:53:01

标签: mongodb aggregate

我有问题列表,他们有这样的结构:

{
    "_id": {
        "$oid": "5a077c418fdf294df73bf7ea"
    },
    "author": "PinkyaRabbit",
    "question": "Что здесь литерал: var x = {};",
    "category": "Javascript шаблоны",
    "answers": [
        "var x",
        "{}",
        "var x = {};",
        "Нету тут его"
    ],
    "real": "{}",
    "description": "Литерал, это нейкое чистое значение, которое встречается в коде. Цифра, слово, объект - что  угодно",
    "users": [
        {
            "status": "good",
            "wasToday": true,
            "user": 471317129
        }
    ],
    "blockedBy": [],
    "date": "2017-11-12T01:40:01+03:00"
}

我需要为用户挑选一个随机的问题。每个用户都有个人类别列表。 blockedBy如果用户不想接受它就是一个数组。我选择了类似数组user.categories的个人类别列表,并尝试进行聚合请求。

TGquestions.aggregate([
          { $match: {
              users:{
                "status": "clear",
                "wasToday": false,
                "user": chatid
              },
              category: { $in: user.categories },
              blockedBy: { $ne: chatid}
            }},
            { $sample: { size: 1 } }
          ], (err, qq) => {

问题是看起来像我的随机不工作。例如,首先从类别中选择带有名称“Javascript”的问题,接下来将是“Javascript”中的相同问题,并且接下来将不再结束的白色问题将来自此类别。当此类别中的问题结束时,下一类别的问题相同。最糟糕的是每次类别的队列都是相同的。所以我的随机聚合总计失败了。如何解决这个问题?

UPD。例 我有一个用户

{
"_id": {
"$oid": "5a15aa31457bca063c01248b"
},
"chatid": 213229659,
"username": "iamRB01",
"baned": false,
"name": "Rina",
"categories": ["Javascript", "Java"],
}

某些类别的一些问题。我更改了_id以使其更具可读性。

{
"_id": "1",
"author": "PinkyaRabbit",
"question": "Что здесь литерал: var x = {};",
"category": "Javascript",
"answers": [
"var x",
"{}",
"var x = {};",
"Нету тут его"
],
"real": "{}",
"description": "Литерал, это нейкое чистое значение, которое встречается в коде. Цифра, слово, объект - что  угодно",
"users": [
{
"status": "clear",
"wasToday": false,
"user": 213229659
}
],
"blockedBy": [],
"date": "2017-11-12T01:40:01+03:00"
},
{
"_id": "2",
"author": "PinkyaRabbit",
"question": "Первым признаком конструктора является?",
"category": "Javascript",
"answers": [
"слово new",
"метод construct",
"имя пишется с большой буквы",
"возможно обращение через this"
],
"real": "имя пишется с большой буквы",
"description": "Если имя чего-то пишется с большой буквы в Javascript, то это конструктор (если код писал не криворукий рак)",
"users": [
{
"status": "clear",
"wasToday": false,
"user": 213229659
}
],
"blockedBy": [],
"date": "2017-11-13T16:20:50+03:00"
},
{
"_id": "3",
"author": "Xiroho",
"question": "Для записи пятеричной системы счисления используются цифры -",
"category": "Java",
"answers": [
"01234",
"0123456789",
"01",
"10"
],
"real": "01234",
"description": "",
"users": [
{
"status": "clear",
"wasToday": false,
"user": 213229659
}
],
"date": "2017-11-20T23:31:03+03:00",
"blockedBy": []
},
{
"_id": "4",
"author": "PinkyaRabbit",
"question": "Как проверить, есть ли элемент в массиве",
"category": "Javascript",
"answers": [
"сделать цикл с проверкой if(haystack[i]===needle){return true;}",
"использовать проверку через filter",
"использовать функцию indexOf",
"использовать функцию includes"
],
"real": "использовать функцию includes",
"users": [
{
"status": "clear",
"wasToday": false,
"user": 213229659
}
],
"description": "Хотя indexOf работает верно\nif(array.indexOf(\"test\") > -1){ result++; }\nона проигрывает includes по быстродействию\narray.includes(\"test\")\nпоэтому стоит использовать includes. Тем не менее, не все браузеры поддерживают includes, которая появилась только в 2016 году, поэтому indexOf знать тоже надо",
"blockedBy": [213229659],
"date": "2017-12-01T01:21:09+03:00"
}

我想挑选一个这个集合的随机问题。例如,第一个id = 2,接下来是id 3,接下来是id 1但不是id 4 cuz用户关闭了这个问题。但在我的脚本中,aggregate随机不起作用...... =(

1 个答案:

答案 0 :(得分:0)

答案是嵌套数组中用于选择使用$elemMatch所需的实际结果。

  TGquestions.aggregate([
    { $match: {
        category: { $in: user.categories },
        users: {
          $elemMatch: {
            "status": "clear",
            "wasToday": false,
            "user": chatid
          }},
        blockedBy: { $ne: chatid}
      }},
      { $sample: { size: 1 } }
    ], (err, qq) => {