запрос на поиск, поиск данных конкретного элемента в mongodb

1

У меня есть документ в моем экземпляре mongo в нижнем формате,

{
"_id"   : "08d4a242-08fb-07f7-46e5-8717a81d5b70",
"fname" :   "john",
"created_date" : ISODate("2017-05-24T01:13:06.829Z"),
"customProp"    : [
    [
        "customX","{\"some data related to X \"}"
    ],
    [
        "customY","{\"some data related to Y \"}"
    ],
    [
        "customZ","{\"some data related to Z \"}"
    ]
]

}

элементы/значения, такие как "customX", "customY" и "customZ", необязательно должны быть во всех документах. Как получить все значения во втором элементе массива "customProp", в этом документе содержится "customZ"?

Я могу использовать следующий запрос для фильтрации и поиска всех документов, имеющих элемент "customZ",

db.getCollection('col1').find({$and : [{"customProp":{$elemMatch:{0:"customZ"}}}, {"created": { $gte: ISODate("2017-05-22T00:00:00.000Z") }}] },{"created":1}).limit(1) .pretty()   

выход:

    {
        "_id" : "08d4a242-08fb-07f7-46e5-8717a81d5b45",
        "created" : ISODate("2017-05-24T01:13:06.829Z")
}

но найти способ получить все значения во втором элементе массива, где первым значением является "customZ".

ожидаемый результат:

   {
    "_id" : "08d4a242-08fb-07f7-46e5-8717a81d5b45",
    "created" : ISODate("2017-05-24T01:13:06.829Z"),
    "customPro": ["customZ","{\"some data related to Z \"}"]
    }

Я в порядке, если мой запрос просто вернется

{
"{\"some data related to Z \"}"
}
Теги:
pymongo

1 ответ

1
Лучший ответ

Ну, это вложенный массив, который не является отличной идеей, но вы фактически сопоставляете элемент с выражением $elemMatch, так что вы получаете позицию во внешнем массиве customProp, что позволяет проецировать с позиционным $ operator:

db.getCollection('coll1').find(
  { 
    "customProp":{ "$elemMatch": { "0": "customZ" } }, 
    "created_date": { "$gte": ISODate("2017-05-22T00:00:00.000Z") }
  },
  { "created_date": 1, "customProp.$": 1 }
)

Это дает результат:

{
        "_id" : "08d4a242-08fb-07f7-46e5-8717a81d5b70",
        "created_date" : ISODate("2017-05-24T01:13:06.829Z"),
        "customProp" : [
                [
                        "customZ",
                        "{\"some data related to Z \"}"
                ]
        ]
}

Где customProp конечно, все еще находится в вложенном массиве, но при обработке отдельных документов на python вы можете просто получить доступ к свойству в индексе массива:

doc['customProp'][0][1]

Который, конечно, возвращает значение:

'{"some data related to Z "}'

То же самое можно сказать о JavaScript, который в основном идентичен синтаксису. В качестве примера оболочки:

db.getCollection('coll1').find(
  { 
    "customProp":{ "$elemMatch": { "0": "customZ" } }, 
    "created_date": { "$gte": ISODate("2017-05-22T00:00:00.000Z") }
  },
  { "created_date": 1, "customProp.$": 1 }
).map(function(doc) {
  doc['customProp'] = doc['customProp'][0][1];
  return doc;
})

И выход:

{
        "_id" : "08d4a242-08fb-07f7-46e5-8717a81d5b70",
        "created_date" : ISODate("2017-05-24T01:13:06.829Z"),
        "customProp" : "{\"some data related to Z \"}"
}

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

Также обратите внимание, что вам не нужно $and здесь, поскольку все аргументы запроса уже являются условиями И. Это значение по умолчанию для MongoDB, поэтому вам не нужно явно его выражать. Посмотрите, насколько лучше это выглядит без него.

  • 0
    Отлично спасибо.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню