Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
47 views

Python Mongodb

The document provides instructions for connecting to a MongoDB database and performing common operations like getting collections, inserting and querying documents, indexing, and error handling using Python and PyMongo. Key points covered include getting databases and collections, inserting single and bulk documents, unique indexing, sorting query results, date range queries, checking for empty results, and selecting data into a Pandas DataFrame.

Uploaded by

Zheng Jun
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
47 views

Python Mongodb

The document provides instructions for connecting to a MongoDB database and performing common operations like getting collections, inserting and querying documents, indexing, and error handling using Python and PyMongo. Key points covered include getting databases and collections, inserting single and bulk documents, unique indexing, sorting query results, date range queries, checking for empty results, and selecting data into a Pandas DataFrame.

Uploaded by

Zheng Jun
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 9

---

title: python-mongodb
date: 2018-10-23 09:27:55
tags: Python
categories: Language
---

use PyMongo

# Getting a Database

```python
# attribute style access
db = client.test_database

# dictionary style access


db = client['test-database']
```

# Getting a Collection

```python
collection = db.test_collection
collection = db['test-collection']
```
<!-- more -->

# 插入数据
```python
collection.insert({'code': code, 'startDate': start_date, 'endDate': end_date,
'klines': klines})
```

## 防止插入重复数据

```python
# 单个字段唯一索引,通过建立索引保证不会重复,降序排列
t_codes.create_index([('trade_date', pymongo.DESCENDING)], unique=True,
background=True)
```

# Error
```
解决 bson.errors.InvalidDocument: Cannot encode object:错误的一种方法
这是因为 pandas 库在读取数值型值时返回的结果不是整型或者浮点型,而是 numpy.int64 类型的一个对象,
mongodb 是无法对一个对象进行编码存储的,所以这里需要对读取到的结果进行强制类型转换
dates = []
for i in range(0, 2):
print(cal.iloc[i]['cal_date'], cal.iloc[i]['is_open'])
print(cal.iloc[i]['cal_date'] + ' %d' %cal.iloc[i]['is_open'])
a = int(cal.iloc[i]['is_open'])
print(type(a))
dates.append({'cal_date':cal.iloc[i]['cal_date'], 'is_open':int(cal.iloc[i]
['is_open'])})

result = calender.insert_many(dates)
print(result)
print(result.inserted_ids)
```

# 查询记录

## 查询返回 datafram

没有数据时返回 datafram 空值

```python
t_data = db[code['ts_code']]
cursor_result = t_data.find(
{'ts_code': code['ts_code'], 'trade_date': {'$gte': start_date.strftime('%Y%m
%d'),
'$lte': end_date.strftime('%Y%m
%d')}}).sort('trade_date',

pymongo.DESCENDING)
labels = ['ts_code', 'trade_date', 'open', 'high', 'low', 'close', 'vol', 'amount']
df = pd.DataFrame(list(cursor_result), columns=labels)
```

## 列出数据库,集合

```python
# 列出数据库
conn.list_database_names()
# 旧版本
conn.database_names()
# 列出集合
db.list_collection_names
# 旧版本
db.collection_names()
```

## 查询所有数据

```python
# 查询集合中的所有文档记录(表中的行记录)
myColl.find()
# 返回一个查询结果的游标,可迭代对象

df = pd.DataFrame(list(t_daily.find({'trade_date': day}, {"_id": 0})))

results = t_codes.find().sort('trade_date', pymongo.DESCENDING).limit(1)


start_trade_date = datetime.datetime.strptime(results[0]['trade_date'], '%Y%m%d')

# $lte less than or equal to


result = t_calender.find(
{'cal_date': {'$gte': pre_base_date.strftime('%Y%m%d'),
'$lte': base_date.strftime('%Y%m%d')}}).sort('cal_date',

pymongo.DESCENDING)
for value in result:
if value['is_open']:
return datetime.datetime.strptime(value['cal_date'], '%Y%m%d')
print('Warning: xx')

# 获得一个游标操作对象,并迭代
rows = handler.find()
for row in rows:
print(row)
```

```python
b. 查询限定操作(也就是 sql 中的 where 语句)
i. myColl.find({'name':'liming'}) 查询集合中 字段 name = liming 的记录
1) 注意:括号内部是一个 字典,或者 json 格式的数据(其实都一个卵样)
2) 字典 key = 集合内文档的字段,value = 字段的值
3) 相当于 sql 中:
select *
from myColl
where name = 'liming'
ii. 一些高级操作:
1) 比较操作:
a) 小于比较:
i) myColl.find({'age':{'$lt':30}}
ii) 查询 age 字段值 小于 30 的所有文档记录
iii) 注意:括号内是一个 字典
iv) 字典 key = 文档字段,value 是一个字典,其中 key = 比较操作符, value =比
较值
v) 相当于 sql 中:
select *
from myColl
where age < 30
b) 其他比较操作符
$gt 大于
$gte 大于等于
$lt 小于
$lte 小于等于
$ne 不等于
2) 组合查询:
a) 逻辑与 and
i) myColl.find({'name':'liming','age':30})
ii) 查询 name = liming 和 age = 30 的所有文档记录
iii) 注意:括号内是一个字典,两个元素。用 逗号分隔开,key = 字段,value=字段值
iv) 相当于 sql:
select *
from myColl
where name = 'liming' and age = 30
b) 逻辑或 or
i) myColl.find({'$or':[{'name':'liming'},{'age':30}]})
ii) 查询 name = 'liming' 或 age = 30 的所有文档记录
iii) 注意:括号内是一个字典,key = '$or' 逻辑或操作符,value = 一个列表
列表内是两个字典,key = 字段,value=字段值
iv) 相当于 sql:
select *
from myColl
where name = 'liming' or age = 30
3) 对查询结果进行排序:
a) myColl.find().sort('name',pymongo.DESCENDING)
i) 对查询结果按照字段 name 进行排序,默认为升序,可以指定排序方向,
DESCENDING 是降序
ii) 相当于 sql:
select *
from myColl
order by name DESC
b) myColl.find().sort([{'name':pymongo.DESEDING',
{'age':pymongo.DESEDING'}])
i) 对查询结果排序,指定排序方向为 降序,默认为升序。
先按照 name 字段排序,在按照 age 字段排序
ii) 相当于 sql:
select *
from myColl
order by name DESC ,age DESC
DESC 关键字只适用于 DESC 前面的字段,需要的话,可以对每个字段指定一次 DESC
```

## 查询返回 dataframe

```python
df = pd.DataFrame(list(t_daily.find({'trade_date': day}, {"_id": 0})))
```

## 删除

```python
# 删除数据库
conn.drop_database('stockAlgPluginData')
conn.drop_database('stockAlgPluginDoc')

# 删除集合
t_codes = db['codes']
t_codes.drop()
# 这里可以重新插入数据,会创建新的集合

# 也可以使用 db 操作
db.drop_collection(collection_name)
```

# 集合是否存在

```python
collection_list = dbDoc.collection_names()
if table_name not in collection_list:
pass
```

# 插入数据
```python
collection.insert({'code': code, 'startDate': start_date, 'endDate': end_date,
'klines': klines})
```

# Error
```
解决 bson.errors.InvalidDocument: Cannot encode object:错误的一种方法
这是因为 pandas 库在读取数值型值时返回的结果不是整型或者浮点型,而是 numpy.int64 类型的一个对象,
mongodb 是无法对一个对象进行编码存储的,所以这里需要对读取到的结果进行强制类型转换
dates = []
for i in range(0, 2):
print(cal.iloc[i]['cal_date'], cal.iloc[i]['is_open'])
print(cal.iloc[i]['cal_date'] + ' %d' %cal.iloc[i]['is_open'])
a = int(cal.iloc[i]['is_open'])
print(type(a))
dates.append({'cal_date':cal.iloc[i]['cal_date'], 'is_open':int(cal.iloc[i]
['is_open'])})

result = calender.insert_many(dates)
print(result)
print(result.inserted_ids)
```

# 连接数据库

```python
import pymongo
conn = pymongo.MongoClient('127.0.0.1', 27017)
# database name is stock
db = conn['stock']

#有密码连接
import pymongo
mongo_client = pymongo.MongoClient('127.0.0.1', 26666)
mongo_auth = mongo_client.admin #或 mongo_client['admin'] admin 为
authenticationDatabase
mongo_auth.authenticate('用户名', '密码')
```

## upsert

当 key 不存在的时候执行插入操作,当存在的时候更新除 key 以外的 set 内的值

最后的参数 True ,则是指明,当 update 不存在的_id 时,执行插入操作。默认是 false,只更新,不插入。

```python
collectionConfig.update({'_id': resultConfig['id']}, {'$set': {'trade_data': 1}},
True)
```

# 单条插入

```python
result = collection.insert_one(student)
print(result)
print(result.inserted_id)
```

# 批量插入

```python
# 创建集合,相当于表
t_codes = db['codes']
# 插入获取的代码
result = t_codes.insert_many(dataArr)
print(result)
print(result.inserted_ids)
```

# 索引

```python
t_codes = db['codes']
# 获取所有索引
all_index = t_codes.index_information()
# print(list(all_index))
# 判断有无索引
has_id_index = all_index.get("idx_ts_code", False)
if has_id_index:
# 是否为唯一索引
if all_index['idx_ts_code'].get('unique', False):
pass
else:
t_codes.drop_index("idx_ts_code")
t_codes.create_index([("ts_code", 1)], name='idx_ts_code', unique=True,
background=True)
else:
t_codes.create_index([("ts_code", 1)], name='idx_ts_code', unique=True,
background=True)

```

# 查找

## 返回是否为空

```python
if not results.count():
print('not empty')
else:
print('empty')
```

## 查询返回 datafram

没有数据时返回 datafram 空值

```python
t_data = db[code['ts_code']]
cursor_result = t_data.find(
{'ts_code': code['ts_code'], 'trade_date': {'$gte': start_date.strftime('%Y%m
%d'),
'$lte': end_date.strftime('%Y%m
%d')}}).sort('trade_date',

pymongo.DESCENDING)
labels = ['ts_code', 'trade_date', 'open', 'high', 'low', 'close', 'vol',
'amount']
df = pd.DataFrame(list(cursor_result), columns=labels)
```

## 查询一条
```python
# 查询第一条数据
row = handler.find_one()
print(row)

# 最后一条
row = handler.find_one(sort=[('_id', -1)])
```

## 选择到 dataframe

```python
t_codes = dbDoc['codes']
cursor = t_codes.find({'list_date':{'$lte': lt_date}}, {"_id": 0, "ts_code": 1,
"name": 1, "list_date": 1})
fields = ['ts_code','name','list_date']
df = DataFrame(list(cursor), columns=fields)
return df
```

## 排序

```python
rows = handler.find().sort('_id', -1)
for row in rows:
print(row) # 此时会倒序输出内容
```

## 时间范围

```python
result = t_codes.find({'trade_date':{'$gte':start,'$lte':end}}).sort('trade_date',
pymongo.DESCENDING)
```

```python
# 查询集合中的所有文档记录(表中的行记录)
myColl.find()
# 返回一个查询结果的游标,可迭代对象

results = t_codes.find().sort('trade_date', pymongo.DESCENDING).limit(1)


start_trade_date = datetime.datetime.strptime(results[0]['trade_date'], '%Y%m%d')

result = t_calender.find(
{'cal_date': {'$gte': pre_base_date.strftime('%Y%m%d'),
'$lte': base_date.strftime('%Y%m%d')}}).sort('cal_date',

pymongo.DESCENDING)
for value in result:
if value['is_open']:
return datetime.datetime.strptime(value['cal_date'], '%Y%m%d')
print('Warning: xx')
```

```python
b. 查询限定操作(也就是 sql 中的 where 语句)
i. myColl.find({'name':'liming'}) 查询集合中 字段 name = liming 的记录
1) 注意:括号内部是一个 字典,或者 json 格式的数据(其实都一个卵样)
2) 字典 key = 集合内文档的字段,value = 字段的值
3) 相当于 sql 中:
select *
from myColl
where name = 'liming'
ii. 一些高级操作:
1) 比较操作:
a) 小于比较:
i) myColl.find({'age':{'$lt':30}}
ii) 查询 age 字段值 小于 30 的所有文档记录
iii) 注意:括号内是一个 字典
iv) 字典 key = 文档字段,value 是一个字典,其中 key = 比较操作符, value =比
较值
v) 相当于 sql 中:
select *
from myColl
where age < 30
b) 其他比较操作符
$gt 大于
$gte 大于等于
$lt 小于
$lte 小于等于
$ne 不等于
2) 组合查询:
a) 逻辑与 and
i) myColl.find({'name':'liming','age':30})
ii) 查询 name = liming 和 age = 30 的所有文档记录
iii) 注意:括号内是一个字典,两个元素。用 逗号分隔开,key = 字段,value=字段值
iv) 相当于 sql:
select *
from myColl
where name = 'liming' and age = 30
b) 逻辑或 or
i) myColl.find({'$or':[{'name':'liming'},{'age':30}]})
ii) 查询 name = 'liming' 或 age = 30 的所有文档记录
iii) 注意:括号内是一个字典,key = '$or' 逻辑或操作符,value = 一个列表
列表内是两个字典,key = 字段,value=字段值
iv) 相当于 sql:
select *
from myColl
where name = 'liming' or age = 30
3) 对查询结果进行排序:
a) myColl.find().sort('name',pymongo.DESCENDING)
i) 对查询结果按照字段 name 进行排序,默认为升序,可以指定排序方向,
DESCENDING 是降序
ii) 相当于 sql:
select *
from myColl
order by name DESC
b) myColl.find().sort([{'name':pymongo.DESEDING',
{'age':pymongo.DESEDING'}])
i) 对查询结果排序,指定排序方向为 降序,默认为升序。
先按照 name 字段排序,在按照 age 字段排序
ii) 相当于 sql:
select *
from myColl
order by name DESC ,age DESC
DESC 关键字只适用于 DESC 前面的字段,需要的话,可以对每个字段指定一次 DESC
```

You might also like