鍍金池/ 問答/Python  數(shù)據(jù)庫/ Pymongo 聚合查詢條件不在表內(nèi)的情況的方法。

Pymongo 聚合查詢條件不在表內(nèi)的情況的方法。

用戶表關(guān)聯(lián)消費(fèi)表
想查詢3個(gè)月未消費(fèi)的用戶
match2的條件
順便請(qǐng)教下 如下這種條件多的 如何優(yōu)化?

match0 = {'$match': {'regDate': {'$gte': day_30, '$lt': today}}}
match1 = {'$match': {'consume.consumeDate': {'$gte': day_180, '$lte': today}}}
match2 = {'$match': {'consume': None}}
match3 = {'$match': {'recharge.rechargeDate': {'$gte': day_30, '$lte': today}}}
match4 = {'$match': {'recharge.tradeNo': {'$ne': ''}}}
lookup1 = {'$lookup': {
    'from': 'consume',
    'localField': '_id',
    'foreignField': 'uid',
    'as': 'consume'
}}
lookup2 = {'$lookup': {
    'from': 'recharge',
    'localField': '_id',
    'foreignField': 'uid',
    'as': 'recharge'
}}
project = {'$project': {
    '_id': 1,
    'regDate': 1,
    'consume.amount': 1,
    'consume.consumeDate': 1,
    'recharge.real': 1,
    'recharge.from': 1,
    'recharge.rechargeDate': 1
}}
group = {'$group': {
    '_id': {
        '_id': '$_id',
    }
}}
pipeline = [match0, lookup1, lookup2, match1, match2, match3, match4, project, group]
result = col_user.aggregate(pipeline)
LossUser = 0
for _ in result:
    LossUser = LossUser + 1
print(LossUser)

回答
編輯回答
風(fēng)畔

1.match2的條件 這個(gè)None是啥意思,如果是想查詢consume這個(gè)字段是否存在,可以改成

{'$match': {'consume': {$exist:true}}}

2.這種優(yōu)化,我曾經(jīng)問過專業(yè)的大神@Mongoing中文社區(qū),我來班門弄斧一下,你這種查詢我猜測會(huì)很慢,但是慢的原因不在于match寫得有問題,而是lookup太慢了,十分影響效率,mongodb是非關(guān)系型數(shù)據(jù)庫,本身設(shè)計(jì)就不想要關(guān)系(我猜的哈),所以lookup和其它查詢關(guān)系的并不是它的強(qiáng)項(xiàng),而且你這里查詢的是消費(fèi)記錄和充值記錄,這兩個(gè)完全是可能不會(huì)更改的數(shù)據(jù),所以我建議是更改數(shù)據(jù)結(jié)構(gòu),將consume和recharge直接存放在這個(gè)user下面,然后不用lookup,直接篩選就可以了,這樣絕對(duì)會(huì)很快,當(dāng)然這前提是在業(yè)務(wù)允許的情況下,修改數(shù)據(jù)結(jié)構(gòu)。
下面貼出我大哥的回答
mongodb的關(guān)聯(lián)查詢$lookup
ps:而且我做過一個(gè)實(shí)驗(yàn),20條數(shù)據(jù)都要lookup的情況下,我查兩次數(shù)據(jù)庫(先查出lookup之前的數(shù)據(jù),再用lookup的根據(jù)(比如說_id)去再查一次數(shù)據(jù)庫,再把這兩者的結(jié)果整合成我想要的數(shù)據(jù))都比直接lookup要快。。。。

2018年6月7日 01:27