Одно из преимуществ MongoDB как лидера в области нереляционных баз данных заключается в том, что она может хранить данные объектного типа в документе и надлежащим образом увеличивать избыточность, чтобы сделать базу данных более доступной.лучше использовать. Один тип объекта документа вызывается в MongoDBВстроенный документ (встроенный), которая также является формой хранения, рекомендованной MongoDB. В этой статье будет представлен метод запроса встроенных документов на основе официальных документов.
1. Применимые сценарии для встроенных документов
Для технической группы начинающей компании быстро меняющиеся требования избавляют от необходимости тратить слишком много усилий на разработку таблиц данных со строгими отношениями, но могут напрямую объединять связанные поля данных, например следующий дизайн:
db.books.insertMany( [
{ _id: 1, name: "python", price: 25, size: { h: 14, w: 21}, reading: ["Tom","John"] },
{ _id: 2, name: "mongo", price: 50, size: { h: 8.5, w: 11}, reading: ["John","Dave"] },
{ _id: 3, name: "webGL", price: 80, size: { h: 8.5, w: 11}, reading: ["Lily"] },
]);
Если вы используете первичный ключ реляционных данных, способ использования _id в качестве ссылки следующий:
db.books.insertMany( [
{ _id: 1, name: "python", price: 25, h: 14, w: 21, reading: ["Tom","John"] },
{ _id: 2, name: "mongo", price: 50, h: 8.5, w: 11, reading: ["John","Dave"] },
{ _id: 3, name: "webGL", price: 80, h: 8.5, w: 11, reading: ["Lily"] },
]);
db.reading.insertMany( [
{ _id: 4, reader: "Tom", book_id:1 },
{ _id: 5, reader: "John", book_id:1 },
{ _id: 6, reader: "John", book_id:2 },
{ _id: 7, reader: "Dave", book_id:2 },
{ _id: 8, reader: "Lily", book_id:3 },
]);
Напротив, встроенный подход имеет следующие преимущества:
- Количество пользовательских запросов уменьшается, и относительно полная соответствующая информация может быть быстро читается
- Использование объекта словаря и списка объектов для увеличения полей и элементов исключительно просто
Встроенные документы могут уменьшить влияние изменения поля на вызывающего абонента. Например, добавление подполя с именем "l" под полем размера для указания длины книги. Для вызывающего абонента его нужно только вынуть из объекта размера. при его использовании Да, нет необходимости дополнительно приобретать новые поля. Поэтому, когда встроенный документ небольшой и частота обновления невелика, рекомендуется использовать встроенный документ для хранения данных.
2. Метод запроса со встроенным документом в качестве словаря
Взяв данные в 1 в качестве примера, для запроса поля с одним значением вам нужно написать только одинсловарь запросов(фильтр запроса) для:
db.books.find( { price: 25 } );
Когда состояние запроса включает подпунки в встроенном документе, используйте «». (Может использоваться постепенно):
db.books.find( { "size.h": 8.5 } );//针对字典对象
-->[
{ _id: 2, name: "mongo", price: 50, size: { h: 8.5, w: 11}, reading: ["John","Dave"] },
{ _id: 3, name: "webGL", price: 80, size: { h: 8.5, w: 11}, reading: ["Lily"] },
]
db.books.find( { "reading.0": "Tom" } );//针对列表
-->[
{ _id: 1, name: "python", price: 25, h: 14, w: 21, reading: ["Tom","John"] },
]
Обратите внимание, что отсутствие использования «.» будет строго соответствовать встроенным документам:
db.books.find( { "size": { h: 8.5} } );//不存在size字段为{ h: 8.5}的文档
-->[]
Как и в случае с обычными запросами, вы можете использоватьОператор Оператор запроса:
db.books.find( { "size.w": { $lt: 21} } );
-->[
{ _id: 2, name: "mongo", price: 50, size: { h: 8.5, w: 11}, reading: ["John","Dave"] },
{ _id: 3, name: "webGL", price: 80, size: { h: 8.5, w: 11}, reading: ["Lily"] },
]
3. Метод запроса о том, что встроенный документ представляет собой список
Пример данных
db.books.insertMany( [
{ _id: 1, name: "python", price: 25, size: [14,21], reading: ["Tom","John"] },
{ _id: 2, name: "mongo", price: 50, size: [8.5,11], reading: ["John","Dave"] },
{ _id: 3, name: "webGL", price: 80, size: [8.5,11], reading: ["Lily"] },
]);
(1) указанное значение списка {ключ: [значение]} должно соответствовать списку условий
Взяв в качестве примера данные в 1, указание списка будет строго следовать всем элементам и их порядку:
db.books.find( { reading: ["Tom","John"]" });
-->[
{ _id: 1, name: "python", price: 25, size: size: [14,21], reading: ["Tom","John"] },
]
Если требуется существование только указанных элементов и порядок не требуется, используйте$all:
db.books.find( { reading: { $all: ["John"] } });
-->[
{ _id: 1, name: "python", price: 25, size:[14,21], reading: ["Tom","John"] },
{ _id: 2, name: "mongo", price: 50, size:[8.5,11], reading: ["John","Dave"] },
]
(2) Указанный элемент {key:value1,value2...} может удовлетворять хотя бы одному элементу для каждого условия значения, не требуется, чтобы один элемент удовлетворял всем условиям одновременно
db.books.find( { reading: "John" });//只要列表中有一元素的值为"John"即满足
-->[
{ _id: 1, name: "python", price: 25, size:[14,21], reading: ["Tom","John"] },
{ _id: 2, name: "mongo", price: 50, size:[8.5,11], reading: ["John","Dave"] },
]
db.books.find( { size: { $gt: 16, $lt: 15} });//只要列表中有一元素的值大于16,还有一元素小于15即满足
-->[
{ _id: 1, name: "python", price: 25, size: [14,21], reading: ["Tom","John"] },
]
(3) Укажите элемент {key:{$elemMatch:value1,value2...}}, если хотя бы один элемент одновременно соответствует условиям каждого значения.
использовать$elemMatch
db.books.find( { size: { $elemMatch: { $gt: 22, $lt: 30 } } });
-->[
{ _id: 1, name: "python", price: 25, size: [14,21], reading: ["Tom","John"] },
]
(4) Укажите длину списка {key:{ $size: value... }}, чтобы удовлетворить условию
использовать$size
db.books.find( { reading: { $size: { $gt: 1} } });
-->[
{ _id: 3, name: "webGL", price: 80, size: [8.5,11], reading: ["Lily"] },
]
Подводя итог, для встроенных документов типа списка, условие сопоставления, заданное $ ELEMMATCH, требует удовлетворенности, чтобы хотя бы один элемент был удовлетворен одновременно, и условие сопоставления без Elemmatch требуется только для удовлетворения по меньшей мере одним элементом.