获取集合中所有键的名称(某些特定键除外)

时间:2017-12-12 02:56:22

标签: mongodb pymongo

MongoDB Get names of all keys in collection类似,由 Veeram

回答

试试这个:

db.basic.insertMany([{'foruse':'basic','company':'ABC','year':1963,'location':'Tokyo'},{"foruse":"develop","equipment":"nb","price":24000},{"foruse":"develop","equipment":"smt","price":1800000},{'foruse':'production','status':'happy','default':'000','SeriesA':'000','SeriesXX':'000'},{'foruse':'production','status':'sad','default':'010','SeriesA':'010','SeriesY':'010','SeriesQ':'202'},{'foruse':'production','status':'cry','default':'020','SeriesA':'020','SeriesXX':'101'},{'foruse':'production','status':'sleep','default':'001','SeriesA':'001','SeriesY':'001'}]);

这就是我的数据

{ "foruse" : "basic", "company" : "ABC", "year" : 1963, "location" : "Tokyo" }
{ "foruse" : "develop", "equipment" : "nb", "price" : 24000 }
{ "foruse" : "develop", "equipment" : "smt", "price" : 1800000 }
{ "foruse" : "production", "status" : "happy", "default" : "000", "SeriesA" : "000", "SeriesXX" : "000" }
{ "foruse" : "production", "status" : "sad", "default" : "010", "SeriesA" : "010", "SeriesY" : "010", "SeriesQ" : "202" }
{ "foruse" : "production", "status" : "cry", "default" : "020", "SeriesA" : "020", "SeriesXX" : "101" }
{ "foruse" : "production", "status" : "sleep", "default" : "001", "SeriesA" : "001", "SeriesY" : "001" }

我想找到除_idforusestatus foruse = "production"以外的密钥,并获取结果

{'_id': 'null', 'allkeys': ['default', 'SeriesA', 'SeriesXX', 'SeriesY', 'SeriesQ']}

但是,如果我尝试这个,那么在将'_id':0, 'foruse':0, 'status':0,添加到以下脚本时会显示错误

db.basic.aggregate([
    {'$match': {'foruse': 'production'}},
    {'$project': {'_id':0, 'foruse':0, 'status':0, 'arrayofkeyvalue': {'$objectToArray': "$$ROOT"}}}, 
    {'$unwind':"$arrayofkeyvalue"}, 
    {'$group':{'_id': 'null', 'allkeys':{'$addToSet':"$arrayofkeyvalue.k"}}}
])

错误讯息:

assert: command failed: {
    "ok" : 0,
    "errmsg" : "Bad projection specification, cannot include fields or add computed fields during an exclusion projection: { _id: 0.0, foruse: 0.0, status: 0.0, arrayofkeyvalue: { $objectToArray: \"$$ROOT\" } }",
    "code" : 40182,
    "codeName" : "Location40182"
} : aggregate failed
_getErrorWithCode@src/mongo/shell/utils.js:25:13
doassert@src/mongo/shell/assert.js:16:14
assert.commandWorked@src/mongo/shell/assert.js:370:5
DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1319:5
@(shell):1:1

2017-12-12T10:55:53.111+0800 E QUERY    [thread1] Error: command failed: {
        "ok" : 0,
        "errmsg" : "Bad projection specification, cannot include fields or add computed fields during an exclusion projection: { _id: 0.0, foruse: 0.0, status: 0.0, arrayofkeyvalue: { $objectToArray: \"$$ROOT\" } }",
        "code" : 40182,
        "codeName" : "Location40182"
} : aggregate failed :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
doassert@src/mongo/shell/assert.js:16:14
assert.commandWorked@src/mongo/shell/assert.js:370:5
DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1319:5
@(shell):1:1

我可以在pymongo中得到我想要的东西

pipeLine = [
            {'$match': {'context': 'light'}}, 
            {'$project': {'arrayofkeyvalue': {'$objectToArray': "$$ROOT"}}}, 
            {'$unwind':"$arrayofkeyvalue"}, 
            {'$group':{'_id':'null', 'allkeys':{'$addToSet':"$arrayofkeyvalue.k"}}} ]
qry = db.basic.aggregate(pipeLine)
for theCursor in qry:
    for allResult in theCursor:
        if allResult == 'allkeys':
            for valueInList in theCursor[allResult]:
                if valueInList not in ['_id', 'foruse', 'status']:
                    print(valueInList)
default
SeriesA
SeriesXX
SeriesY
SeriesQ

有简单的方法吗?

1 个答案:

答案 0 :(得分:1)

这是我对pymongo的回答 reference for setDifference

p = list(db.basic.aggregate([
    {'$match': {'context': 'light'}},
    {'$project': {'arrayofkeyvalue': {'$objectToArray': "$$ROOT"}}}, 
    {'$unwind':"$arrayofkeyvalue"}, 
    {'$group':{'_id': 'null', 'allkeys':{'$addToSet':"$arrayofkeyvalue.k"}}},
    {'$project':{'allkeys':{'$setDifference':['$allkeys',['foruse','status']]}}}
]))