I'm looking to build a question answer survey system where some questions will be based on the answer of the parent question. The hierarchy level of the questions can go any number of depth based on the questions. The questions and answers will be like the diagram shown here.
I'm looking to build this in mongodb. I have checked the tree model in mongodb and I'm clueless on how to structure it as the next set of questions are depends on the answers. The questions should show based on what answer the user have selected and some answers may have multiple question sets below that as well (E.g.: Ans B).
Can someone help me on the mongodb collection structure and how can I query the next set of questions and answers based on the previous answer given by the user? Thanks in advance.
2 Answers 2
If the whole survey is not too big and if it will not grow, I would consider putting all the questions and answers inside one document.
So one document of that collection would look like
{
"survey": {
"Question A": [
{
"Ans A": [
{
"Question C": [...]
}
]
},
{
"Ans B": [
{
"Question D": [...],
"Question E": [...]
}
]
}
]
}
}
If it is big, and could grow in future, I would consider putting answer and question ids as key-value pair like following.
{
"title": "Question A",
"answers": [
{
"Ans A": [
"Question C's Id"
]
},
{
"Ans B": [
"Question D's Id",
"Question E's Id"
]
}
]
}
I wouldn't normalize to have both question and answer collection, because it would take too much time to join each other.
-
Thanks for the structure. I think the second structure would work well for my scenario. Can you tell me how can I query the next set of questions at once for each direction?User 99x– User 99x2020年06月04日 10:21:56 +00:00Commented Jun 4, 2020 at 10:21
-
If one chose answer B at question A, then
db.questions.find({_id: {$in: ["Question D's Id", "Question E's Id"]}})
will find next set of questions.Kyoosik Lee– Kyoosik Lee2020年06月05日 01:32:13 +00:00Commented Jun 5, 2020 at 1:32
The questions should show based on what answer the user have selected and some answers may have multiple question sets below that as well (E.g.: Ans B).
Can someone help me on the mongodb collection structure and how can I query the next set of questions and answers based on the previous answer given by the user?
This can be modeled in different ways. Here is a possible solution.
The data is in two collections with following structures: questions
and answers
questions:
{
_id: "question-1",
description: "The question is ... ",
answers: [ "ans-1", "ans-2" ]
}
Note the answers
array has _id
values referencing the answers
collection.
answers:
{
_id: "ans-1",
description: "The answer is ... ",
questions: [ "question-2", "question-3" ]
}
Note the questions
array has _id
values referencing the questions
collection.
To simplify, the sample data below doesn't show the description
field. The data is derived from the diagram from the question post.
Questions data:
[
{ _id: 'q_a', answers: [ 'a_a', 'a_b' ] },
{ _id: 'q_b', answers: [ 'a_k', 'a_j' ] },
{ _id: 'q_c', answers: [ 'a_c', 'a_d', 'a_e' ] },
{ _id: 'q_d', answers: [ 'a_f', 'a_g' ] },
{ _id: 'q_e', answers: [ 'a_h', 'a_i' ] },
{ _id: 'q_f', answers: [ 'a_l', 'a_m' ] },
{ _id: 'q_g', answers: [ 'a_n', 'a_o' ] }
]
Answers data:
[
{ _id: 'a_a', questions: [ 'q_c' ] },
{ _id: 'a_b', questions: [ 'q_d', 'q_e' ] },
{ _id: 'a_c', questions: null },
{ _id: 'a_d', questions: [ 'q_g' ] },
{ _id: 'a_e', questions: null },
{ _id: 'a_f', questions: null },
{ _id: 'a_g', questions: null },
{ _id: 'a_h', questions: null },
{ _id: 'a_i', questions: null },
{ _id: 'a_j', questions: [ 'q_f' ] },
{ _id: 'a_k', questions: null },
{ _id: 'a_l', questions: null },
{ _id: 'a_m', questions: null },
{ _id: 'a_n', questions: null },
{ _id: 'a_o', questions: null }
]
Note the questions
field as null
indicates that there are no following questions for this answer.
Assuming that the user selected answer value is "a_b"
, the following query returns the corresponding questions (and their possible answers).
db.answers.aggregate([
{
$match: {
_id: "a_b"
}
},
{
$lookup: {
from: "questions",
localField: "questions",
foreignField: "_id",
as: "next_q_a"
}
}
])
This outputs:
[
{
_id: 'a_b',
questions: [ 'q_d', 'q_e' ],
next_q_a: [
{ _id: 'q_d', answers: [ 'a_f', 'a_g' ] },
{ _id: 'q_e', answers: [ 'a_h', 'a_i' ] }
]
}
]