Запрашивания этой структуры для результатов вы хотите не представляется возможное, не зная все возможные forms
имен заранее, и использовать их в запросе. Во всяком случае, это было бы очень грязно. Тем не менее, читайте дальше, объясняя, как это можно сделать.
Существует проблема со структурой этих документов, которая предотвратит проведение разумного анализа запросов. В его нынешнем виде вы должны знать все возможные поля имени формы, чтобы отфильтровывать что-либо.
В вашей текущей структуре есть формы, содержащие поддокумент, из которых каждый ключ содержит другой поддокумент с одним свойством, status
. Это трудно выполнить, поскольку ваш элемент forms
имеет произвольную структуру для каждого создаваемого вами документа. Это означает, что шаблон сходит в status
информацию, которую вы хотите сравнить с изменениями для каждого документа в вашей коллекции.
Вот что я имею в виду по пути. Для того, чтобы получить в состоянии в любом элементе вы должны сделать следующие
формы ->PreOp -> Статус
Формы ->оповещения -> Статус
Со вторым элемент постоянно меняется. Существует нет пути до wildcard что-то вроде этого, поскольку именование считается явным.
Это, возможно, был рассмотрен простым способ реализации сериализации данных из ваших форм но я вижу более гибкой альтернативы. Вам нужна структура документа, которую вы можете перемещать по стандартной схеме. Это всегда стоит рассматривать в дизайне. Возьмем следующее:
{
"_id" : "Tvq444454j",
"name": "Jim",
"forms": [
{
"name": "Jorney",
"status":"closed"
},
{
"name": "Women",
"status":"void"
},
{
"name": "Child",
"status":"closed"
},
{
"name": "Farm",
"status":"closed"
}
]
}
Так структура документа изменяется, чтобы сделать forms
элемент является массивом, и вместо того, поместить поле статуса под ключ, который называет «поле формы» мы имеем каждый член Массив в качестве поддокумента, содержащего «поле формы» name
и status
. Таким образом, и идентификатор, и статус все еще соединены вместе, но представлены только как суб-документ.Это самое главное изменяет путь доступа к этим клавишам, так как теперь для как название поля и его статус мы можем сделать
формы ->статус
или
формы ->имя
Что это означает, что вы можете запросить, чтобы найти имена всех полей в form
или все поля status
в form
или даже все документы с определенным полем name
и определенными status
. То есть много лучше, чем можно было бы сделать с исходной структурой.
Теперь в вашем конкретном случае, вы хотите получить только документы, где все поля не void
. Теперь в одном запросе нет способа сделать это, так как нет никакого оператора для сравнения всех элементов в массиве таким образом и посмотреть, являются ли они одинаковыми. Но есть два подхода, которые Вы можете взять с собой:
Первый и, вероятно, не столь эффективен для запроса всех документов, которые содержат элемент forms
, который имеет status
из «пустоты». С полученным в результате документом Id вы можете отправить другой запрос, который возвращает документы, которые не имеют идентификаторы, которые были указаны.
db.forms.find({ "forms.status": "void" },{ _id: 1})
db.forms.find({ _id: $not: { $in: [<Object1>,<Object2>,<Object3>,... ] } })
Учитывая размер результата это не может быть возможно, и, как правило, не является хорошей идеей, поскольку оператор исключения $not
в основном вынуждает полное сканирование коллекции, так что вы не могли бы использовать индекс.
Другой подход заключается в использовании трубопровода агрегирования следующим образом:
db.forms.aggregate([
{ "$unwind": "$forms" },
{ "$group": { "_id": "$_id", "status": { "$addToSet": "$forms.status" }}},
{ "$unwind": "$status" },
{ "$sort": { "_id": 1, "status": -1 }},
{ "$group": { "_id": "$_id", "status": { "$first": "$status"}}},
{ "$match":{ "status": "closed" }}
])
Конечно, это будет только вернуть _id для документов, которые соответствуют, но вы можете оформить запрос с $ в и вернуть все совпадения документы. Это лучше, чем оператор исключения, используемый ранее, и теперь мы можем использовать индекс, чтобы избежать полного сканирования коллекции.
В качестве окончательного подхода и для оценки эффективности работы вы можете изменить документ еще раз, чтобы на верхнем уровне вы сохранили «статус» того, какое поле в формах «пусто» или «закрыто», , Таким образом, на верхнем уровне значение будет закрыто только в том случае, если все элементы были «закрыты» и «недействительны», если что-то было недействительным, и так далее.
Это окончательное будет означать дальнейшее изменение программы, и все изменения в элементах forms
также должны будут обновить это поле и сохранить «статус». Тем не менее, это самый эффективный способ найти нужные вам документы и заслуживает рассмотрения.
EDIT:
Помимо изменения документа, чтобы иметь статус мастера, быстрый форму запроса на измененную структуру на самом деле:
db.forms.find({ "forms": { "$not": { "$elemMatch": { "status": "void" } } } })
Вы должны получить все документы или все _ids? Кроме того, вам нужно отфильтровать документы, которые имеют определенную форму со статусом «void» или ** any ** status «void»? – Jinxcat
Я хочу получить все документы, где каждый документ имеет все формы в «закрытом» статусе не в «void» –
Является ли список имен форм конечным (указанным)? – Jinxcat