1

I want to get random question from the list, and i want to sort randomly the option, i tried and i get the random question, but i don`t know how to sort randomly from the array.

this is my sample

{ 'question': 'question 1...', 'option': [{ 'id': '1', 'text': 'opt1' }, { 'id': '2', 'text': 'opt2' }, { 'id': '3', 'text': 'opt3' }] },
{ 'question': 'question 2...', 'option': [{ 'id': '1', 'text': 'opt1' }, { 'id': '2', 'text': 'opt2' }, { 'id': '3', 'text': 'opt3' }, { 'id': '4', 'text': 'opt4' }, { 'id': '5', 'text': 'opt5' }] },
{ 'question': 'question 3...', 'option': [{ 'id': '1', 'text': 'opt1' }, { 'id': '2', 'text': 'opt2' }, { 'id': '3', 'text': 'opt3' }] },
{ 'question': 'question 4...', 'option': [{ 'id': '1', 'text': 'opt1' }, { 'id': '2', 'text': 'opt2' }, { 'id': '3', 'text': 'opt3' }, { 'id': '4', 'text': 'opt4' }] },
{ 'question': 'question 5...', 'option': [{ 'id': '1', 'text': 'opt1' }, { 'id': '2', 'text': 'opt2' }, { 'id': '3', 'text': 'opt3' }] },
db.getCollection('collection').aggregate([
    {
        "$sample": { "size": 3 }
    },
    {
        "$addFields": {
                "option_count": {"$size": "$option"}       
        },
    }
])

i want to get this result

{ 'question': 'question 2...', 'option': [{ 'id': '2', 'text': 'opt2' }, { 'id': '3', 'text': 'opt3' }, { 'id': '1', 'text': 'opt1' }, { 'id': '5', 'text': 'opt5' }, { 'id': '4', 'text': 'opt4' }] },
{ 'question': 'question 5...', 'option': [{ 'id': '3', 'text': 'opt3' }, { 'id': '1', 'text': 'opt1' }, { 'id': '2', 'text': 'opt2' } ] },
{ 'question': 'question 4...', 'option': [{ 'id': '2', 'text': 'opt2' }, { 'id': '3', 'text': 'opt3' }, { 'id': '1', 'text': 'opt1' },   { 'id': '4', 'text': 'opt4' }] },
jexists
  • 171
  • 1
  • 10
  • 1
    Interesting question - not sure if this is possible throgh mongodb, so I'd just use `$sample` to get random question documents and then shuffle the options on the client-side. – eol Jan 12 '22 at 09:18
  • @eol I have the same idea as you because all options are required. It's a good idea to shuffle options on the client side. – YuTing Jan 13 '22 at 00:55

1 Answers1

0

Use $function New in version 4.4.

shuffle

db.collection.aggregate([
  {
    "$sample": {
      "size": 3
    }
  },
  {
    "$set": {
      "option": {
        "$function": {
          "body": "function (arr) {return arr.sort( () => Math.random()-0.5) ;}",
          "args": [
            "$option"
          ],
          "lang": "js"
        }
      }
    }
  }
])

mongoplayground

YuTing
  • 6,555
  • 2
  • 6
  • 16