Агрегация Mongo: удаление пустых документов и возврат разных результатов

#mongodb #aggregation-framework

#mongodb #агрегация-фреймворк

Вопрос:

Я запрашиваю довольно большую коллекцию (более 20 миллионов записей). Мне нужно извлекать только определенные значения полей, и я также хотел бы исключить пустые документы из результатов (документы, которые не имеют каких-либо соответствующих значений), а также сгруппировать по / найти какой-либо другой способ возвращать только уникальные объекты документа, чтобы уменьшить количество возвращаемых записей.

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

 { 
    "_id" : ObjectId("5d4d81f1f7453b000734c603"), 
    "name" : "question_group",
    "questions" : [
        {
            "question_other_field": "testing"
        }
        {
            "question_type" : "newbie", 
            "question_value" : "how to query data"
        }, 
        {
            "question_type" : "newbie", 
            "question_value" : "how to query data",
            "question_metadata" : {
                "question_subject_name" : "Mongo"
            }
        }, 
        {
            "question_type" : "newbie", 
            "question_value" : "how to query data",
            "question_other_field": "testing"
            "question_metadata" : {
                "question_subject_name" : "Mongo"
            }
        }, 
        {
            "question_type" : "expert", 
            "question_value" : "how not to query data", 
            "question_timestamp" : 1556854333, 
            "question_metadata" : {
                "question_subject_name" : "Mongo", 
                "question_answer_id" : "19247100",
                "question_answer_events" : {
                      "attitude" : "helpful",
                      "result" : "success"
                }
            }
        }
    ]
}
  

Для некоторых записей массив вопросов пуст, а когда это не так, иногда определенные внутренние поля и объекты существуют, иногда их нет. И я хочу запросить всю коллекцию и экспортировать только значения для этих полей:

 questions.question_type
questions.question_value
questions.question_metadata.question_subject_name
questions.question_metadata.question_answer_events.attitude
questions.question_metadata.question_answer_events.result
  

Если какое-либо из этих полей является пустым или не существует, это нормально. Но если все поля пусты, я хочу опустить эту строку; Я не хочу, чтобы документ возвращался с нулевыми полями. И, наконец, опять же, поскольку это большая коллекция, я хочу возвращать различные значения, так что, если два или более результирующих документа будут иметь одинаковые пять значений для всех вышеупомянутых пяти полей, я хочу, чтобы они были сгруппированы в одну строку. (На самом деле мне не нужно подсчитывать, сколько в каждой группе, хотя, возможно, это было бы неплохо в дополнение.)

Вот что я в идеале ожидал бы получить обратно при экспорте, основываясь на небольшой выборке примеров данных, которые я привел выше. Есть три результата; первая запись выше отсутствует в результатах, потому что она не содержит ни одного из полей, которые я ищу, а третья и четвертая объединены в одну строку, потому что, хотя они разные, разница не в одном из полей запроса.

 question_type: "newbie"
question_value: "how to query data"
question_subject_name: 
attitude: 
result:

question_type: "newbie"
question_value: "how to query data"
question_subject_name: "Mongo"
attitude: 
result:

question_type: "expert"
question_value: "how not to query data"
question_subject_name: "Mongo"
attitude: helpful 
result: success
  

Я совершенно новичок в Mongo и выполнении запросов, и это лучшее, что я придумал до сих пор:

 db.myCollection.aggregate([
{
    $match: {
        questions: {
            $ne: []
        }
    }
},
{
    $unwind: "$questions"
},
{
    $project: { 
        "_id": 0,
        question_type: "$questions.question_type",
        question_value: "$questions.question_value",
        question_subject_name: "$questions.question_metadata.question_subject_name",
        question_answer_events: "$questions.question_metadata.question_answer_events"
    } 
},
{
    $project: {
        "_id": 0,
        question_type: "$question_type",
        question_value: "$question_value",
        question_subject_name: "$question_subject_name",
        attitude: "$question_answer_events.attitude",
        result: "$question_answer_events.result",
    }
}
])
  

$match и $ unwind могут быть избыточными, если $ unwind уже удаляет строки без массива вопросов, но я не уверен. Кроме того, с помощью этого запроса я получаю неотличимые результаты (потому что я не знаю как), а также возвращаю несколько строк с нулевыми полями, подразумевая (вероятно, правильно), что в исходной строке был массив вопросов, но совершенно другой набор полей.

Для этого бывшего lurker очень ценится любая помощь!

Комментарии:

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

2. Спасибо. Я отредактирую свой вопрос, чтобы прояснить это. Редактирование комментариев не идеально для этого.