2016-06-16 6 views
5

Вот моя структура базы данныхПолучить случайный элемент из массива в MongoDB

{ 
    "_id" : ObjectId("576155226d1d298c2cc3edca"), 
    "questionLibrary" : { 
      "technologyName" : "CSS", 
      "questions" : [ 
        { 
          "correctanswer" : { 
            "A1" : "CSS1" 
          }, 
          "answeroption" : { 
            "A4" : "CSS1", 
            "A3" : "CSS1", 
            "A2" : "CSS1", 
            "A1" : "CSS1" 
          }, 
          "level" : "Amature", 
          "tags" : "CSS", 
          "question" : "CSS1" 
        }, 
        { 
          "question" : "CSS2", 
          "tags" : "CSS", 
          "answeroption" : { 
            "A1" : "CSS2", 
            "A2" : "CSS2", 
            "A3" : "CSS2", 
            "A4" : "CSS2" 
          }, 
          "level" : "Amature", 
          "correctanswer" : { 
            "A1" : "CSS2" 
          } 
        }, 
        { 
          "correctanswer" : { 
            "A1" : "CSS3" 
          }, 
          "answeroption" : { 
            "A4" : "CSS3", 
            "A3" : "CSS3", 
            "A2" : "CSS3", 
            "A1" : "CSS3" 
          }, 
          "level" : "Amature", 
          "tags" : "CSS", 
          "question" : "CSS3" 
        }, 
        { 
          "correctanswer" : { 
            "A1" : "CSS4" 
          }, 
          "answeroption" : { 
            "A4" : "CSS4", 
            "A3" : "CSS4", 
            "A2" : "CSS4", 
            "A1" : "CSS4" 
          }, 
          "level" : "Amature", 
          "tags" : "CSS", 
          "question" : "CSS4" 
        }, 
        { 
          "correctanswer" : { 
            "A1" : "CSS5" 
          }, 
          "answeroption" : { 
            "A4" : "CSS5", 
            "A3" : "CSS5", 
            "A2" : "CSS5", 
            "A1" : "CSS5" 
          }, 
          "level" : "Amature", 
          "tags" : "CSS", 
          "question" : "CSS5" 
        }, 
        { 
          "correctanswer" : { 
            "A1" : "CSS6" 
          }, 
          "answeroption" : { 
            "A4" : "CSS6", 
            "A3" : "CSS6", 
            "A2" : "CSS6", 
            "A1" : "CSS6" 
          }, 
          "level" : "Amature", 
          "tags" : "CSS", 
          "question" : "CSS6" 
        }, 
        { 
          "correctanswer" : { 
            "A1" : "CSS7" 
          }, 
          "answeroption" : { 
            "A4" : "CSS7", 
            "A3" : "CSS7", 
            "A2" : "CSS7", 
            "A1" : "CSS7" 
          }, 
          "level" : "Amature", 
          "tags" : "CSS", 
          "question" : "CSS7" 
        }, 
        { 
          "correctanswer" : { 
            "A1" : "CSS8" 
          }, 
          "answeroption" : { 
            "A4" : "CSS8", 
            "A3" : "CSS8", 
            "A2" : "CSS8", 
            "A1" : "CSS8" 
          }, 
          "level" : "Amature", 
          "tags" : "CSS", 
          "question" : "CSS8" 
        }, 
        { 
          "correctanswer" : { 
            "A1" : "CSS9" 
          }, 
          "answeroption" : { 
            "A4" : "CSS9", 
            "A3" : "CSS9", 
            "A2" : "CSS9", 
            "A1" : "CSS9" 
          }, 
          "level" : "Amature", 
          "tags" : "CSS", 
          "question" : "CSS9" 
        }, 
        { 
          "correctanswer" : { 
            "A1" : "CSS10" 
          }, 
          "answeroption" : { 
            "A4" : "CSS10", 
            "A3" : "CSS10", 
            "A2" : "CSS10", 
            "A1" : "CSS10" 
          }, 
          "level" : "Amature", 
          "tags" : "CSS", 
          "question" : "CSS10" 
        } 
      ] 
    }, 
    "__v" : 3 
} 

Из массива вопроса, я хочу, чтобы получить случайный предмет (случайный вопрос) каждый раз, когда я сгореть запрос.

Я не хочу собирать все объекты одновременно и укомплектовывать их в узле. Можно ли написать запрос так, чтобы он возвращал случайный объект каждый раз?

+2

Предлагает перестроить вашу схему для денормализации массива 'questions' путем хранения данных в отдельной коллекции, например' questions'. Затем вы можете легко использовать оператор контировки [** '$ sample' **] (https://docs.mongodb.com/master/reference/operator/aggregation/sample/#pipe._S_sample) вместе с фильтром на тег, чтобы нарисовать образец документа вопроса. Гораздо проще запросить этот путь. Пример запроса: 'db.questions.aggregate ([{" $ sample ": {" size ": 1}}])' – chridam

ответ

1

Попробуйте эту логику

1) использовать $unwind на массиве «вопросы», если вы используете includeArrayIndex, он будет создавать документы с индексом см examples в размотки документации

2) После того, как раскручивание массив пропускать случайное число, чтобы получить вопрос

1

Вам необходимо де-нормализовать массив вопросов, используя оператор $unwind. Оттуда вы можете использовать оператор конвейера $sample для возврата случайного документа (случайный вопрос).

db.collection.aggregate(
    [ 
     { "$unwind": "$questionLibrary.questions" }, 
     { "$sample": { "size": 1 } } 
    ] 
) 

Но я предлагаю вам изменить структуру документа и сохранить «вопросы» в его собственной коллекции, потому что $unwind может производить очень большой результат.

Смежные вопросы