Статья предполагает что у вас установлена mongodb, работающая на стандартном хосте и порте. Запускаем сервис mongo:
$ mongod
Далее стоит убедиться что у нас установлена PyMongo.
Первым шагом при работе с PyMongo является создание MongoClient для запуска экземпляра mongod:
from pymongo import MongoClient
client = MongoClient()
Таким образом мы подключаемся к стандартному хосту и порту. Чтобы явно указать хост и порт пишем так:
client = MongoClient('localhost', 27017)
Или используя MongoDB URI формат:
client = MongoClient('mongodb://localhost:27017/')
Один экземпляр MongoDB может поддерживать несколько независимых баз данных. Получение доступа к базе данных:
db = client.test_database
А так же следующим образом, если имя вашей базы данных не позволяет использовать предыдущий способ.
db = client['test-database']
Коллекция представляет собой группу документов, хранящихся в MongoDB, и может рассматриваться как эквивалент таблицы в реляционной базе данных. Получить коллекцию в PyMongo можно таким же способом, как и при получение базы данных:
collection = db.test_collection
Или вот так:
>>> collection = db['test-collection']
Важное примечание о коллекциях (и базах данных) в MongoDB. На самом деле при выполнении этих операций базы данных и коллекции физически не создаются. А создаются они при добавлении в эту базу данных и эту коллекцию первого документа.
Данные в MongoDB представлены и хранятся в виде JSON документов . В PyMongo мы используем словари представления документов. В качестве примера, следующий словарь может быть использован для представления поста в блоге:
import datetime
post = {"author": "Mike",
"text": "My first blog post!",
"tags": ["mongodb", "python", "pymongo"],
"date": datetime.datetime.utcnow()}
Обратите внимание, что документы могут содержать собственные типы Python (как datetime.datetime случаях), которые будут автоматически преобразованы в соответствующие типы BSON.
Чтобы добавить документ в коллекции, вы можете использовать метод insert_one ():
posts = db.posts
post_id = posts.insert_one(post).inserted_id
Когда документ будет добавлен, автоматически создается специальный ключ — «_id», если документ уже не содержит таковой. Значение «_id» должно быть уникальным для коллекции. insert_one () возвращает экземпляр InsertOneResult. Для получения более подробной информации о «_id», смотрите в документации по _id.
После добавления первого документа, коллекция post физически создалась на сервере.
>>> db.collection_names(include_system_collections=False)
[u'posts']
Самый простой тип запроса, который может быть выполнен в MongoDB является find_one (). Этот метод возвращает один документ, соответствующий запросу (или ни одного, если не было совпадений). Это полезно, когда вы знаете, что есть только один подходящий документ, или заинтересованы только в первом совпадении. Здесь мы используем find_one (), чтобы получить первый документ из коллекции постов:
>>> posts.find_one()
{u'date': datetime.datetime(...), u'text': u'My first blog post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'mongodb', u'python', u'pymongo']}
В результате мы получили ранее добавленый документ.
Заметка. Возвращенный документ содержит «_id», который был автоматически создан при добавлении.
find_one () также поддерживает запрос на конкретные элемены, которым документ должен соответствовать. Чтобы получить только документы за авторством «Mike» мы делаем так:
>>> posts.find_one({"author": "Mike"})
{u'date': datetime.datetime(...), u'text': u'My first blog post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'mongodb', u'python', u'pymongo']}
Если мы сделаем тоже самое с другим автором мы не получите результата:
>>> posts.find_one({"author": "Eliot"})
>>>
Запросы по ObjectId
Мы также можем найти запись по ее "_id", что в нашем примере - ObjectId:
>>> post_id
ObjectId(...)
>>> posts.find_one({"_id": post_id})
{u'date': datetime.datetime(...), u'text': u'My first blog post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'mongodb', u'python', u'pymongo']}
Обратите внимание, что ObjectId не то же самое, что и его строчное представление:
post_id_as_str = str(post_id)
>>> posts.find_one({"_id": post_id_as_str}) # No result
>>>
В веб-приложениях частой задачей является получение ObjectId из запрашиваемого URL и нахождение соответствующий документ. При этом необходимо преобразовние из строки в ObjectId перед передачей в find_one:
from bson.objectid import ObjectId
# Веб фреймворк получает post_id из URL и передает его в виде строки
def get(post_id):
# Преобразовываем из строки в ObjectId:
document = client.db.collection.find_one({'_id': ObjectId(post_id)})
Обратите внимание на стоки в Unicode
Вы, наверное, заметили, что строки Python, которые мы поместили ранее отличаться, от полученных с сервера (например, u'Mike 'вместо' Майка ').
MongoDB хранит данные в формате BSON. BSON строки в закодированы UTF-8. Поэтому PyMongo должна удостовериться, что любые строки, которые она хранит, содержат данные допустимые в кодировке UTF-8. Регулярные строки ( 'str'>) проверяются и сохраняются неизменными. Unicode строки () сначала кодируются в UTF-8. Причина почему в нашем примере строка представлена в оболочке Python в качестве u'Mike 'вместо 'Mike', в том что PyMongo декодирует каждую BSON строку в юникод.
Вы можете прочитать больше о Юникрде в Python здесь.
Для того, чтобы сделать запросы к БД немного более интереснее, давайте добавим несколько документов. В дополнение к добавлению одного документа, мы также можем выполнять операции массового добавления, проходя по списку в качестве первого аргумента insert_many (). Так мы добавляем каждый документ в списке, посылая только одну команду серверу:
new_posts = [{"author": "Mike",
"text": "Another post!",
"tags": ["bulk", "insert"],
"date": datetime.datetime(2009, 11, 12, 11, 14)},
{"author": "Eliot",
"title": "MongoDB is fun",
"text": "and pretty easy too!",
"date": datetime.datetime(2009, 11, 10, 10, 45)}]
result = posts.insert_many(new_posts)
>>> result.inserted_ids
[ObjectId('...'), ObjectId('...')]
Есть несколько интересных вещей, чтобы отметить о данном примере:
Чтобы получить несколько документов в результате запроса, мы используем метод find(). Find() возвращает экземпляр Cursor, который позволяет нам перебрать все соответствующие документы. Например, мы можем перебрать все документы в коллекции post:
for post in posts.find():
post
...
{u'date': datetime.datetime(...), u'text': u'My first blog post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'mongodb', u'python', u'pymongo']}
{u'date': datetime.datetime(2009, 11, 12, 11, 14), u'text': u'Another post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'bulk', u'insert']}
{u'date': datetime.datetime(2009, 11, 10, 10, 45), u'text': u'and pretty easy too!', u'_id': ObjectId('...'), u'author': u'Eliot', u'title': u'MongoDB is fun'}
Так же, как мы это делали с find_one (), мы можем ограничить возвращаемые find() результаты. Здесь мы получаем только документы, автор которых «Mike»:
for post in posts.find({"author": "Mike"}):
post
...
{u'date': datetime.datetime(...), u'text': u'My first blog post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'mongodb', u'python', u'pymongo']}
{u'date': datetime.datetime(2009, 11, 12, 11, 14), u'text': u'Another post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'bulk', u'insert']}
Если мы просто хотим знать, сколько документов совпадают с запросом мы можем выполнить операцию count() вместо полного запроса. Мы можем получить количество всех документов в коллекции:
>>> posts.count()
3
Или просто из тех документов, которые соответствуют конкретному запросу:
>>> posts.find({"author": "Mike"}).count()
2
MongoDB поддерживает множество различных типов сложных запросов. В качестве примера, давайте выполнить запрос, где мы ограничиваем результаты по дате постов, а также сортируем их по автору:
d = datetime.datetime(2009, 11, 12, 12)
for post in posts.find({"date": {"$lt": d}}).sort("author"):
print post
...
{u'date': datetime.datetime(2009, 11, 10, 10, 45), u'text': u'and pretty easy too!', u'_id': ObjectId('...'), u'author': u'Eliot', u'title': u'MongoDB is fun'}
{u'date': datetime.datetime(2009, 11, 12, 11, 14), u'text': u'Another post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'bulk', u'insert']}
Здесь мы используем специальный оператор «$lt»(less than) чтобы ограничить запросы, а также вызываем sort() для сортировки результатов по автору.
Добавление индексов может помочь ускорить определенные запросы, а также может добавить дополнительную функциональность запросам и хранению документов. В этом примере, мы покажем, как создать уникальный индекс по ключу, который отвергает документы, в которых значение этого ключа уже существует в индексе.
Во-первых, мы должны создать индекс:
result = db.profiles.create_index([('user_id', pymongo.ASCENDING)],
unique=True)
>>> list(db.profiles.index_information())
[u'user_id_1', u'_id_']
Обратите внимание, что у нас теперь есть два индекса: один — указывает на _id, который автоматически создает MongoDB, а другой указывает на user_id, который мы только что создали.
Теперь давайте настроим некоторые пользовательские профили:
user_profiles = [
{'user_id': 211, 'name': 'Luke'},
{'user_id': 212, 'name': 'Ziltoid'}]
result = db.profiles.insert_many(user_profiles)
Индекс мешает добавить документ user_id которого уже в коллекции:
new_profile = {'user_id': 213, 'name': 'Drew'}
duplicate_profile = {'user_id': 212, 'name': 'Tommy'}
result = db.profiles.insert_one(new_profile) # Тут все хорошо.
result = db.profiles.insert_one(duplicate_profile)
Traceback (most recent call last):
pymongo.errors.DuplicateKeyError: E11000 duplicate key error index: test_database.profiles.$user_id_1 dup key: { : 212 }
Если говорить о том, какие лучшие дистрибутивы Linux мы знаем, то этот список может быть…
Хотя Ubuntu и поставляется со встроенным обозревателем Firefox многие пользователи считают что это не самая…
Что такое Remmina? Remmina — это совершенно бесплатный и свободный клиент так называемого удаленного рабочего…
Как мы знаем, Ubuntu это самая популярная сборка из систем на базе ядра Linux. У…
Выбор ноутбука для каждого пользователя это довольно кропотливый процесс. Люди стараются подобрать ноутбук который будет…
Если вы решили ознакомиться с операционной системой Linux более детально и задались вопросом как установить…