Reputation: 604
Similar to MongoDB Get names of all keys in collection, answered by Veeram
Try this:
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'}]);
This is what my data looks like
{ "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" }
I want to find the keys except _id
, foruse
, status
where foruse = "production"
, and get the result
{'_id': 'null', 'allkeys': ['default', 'SeriesA', 'SeriesXX', 'SeriesY', 'SeriesQ']}
But what if I try this, it shows me an error when adding '_id':0, 'foruse':0, 'status':0,
to the following script
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"}}}
])
Error message:
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
I can get what I want using this in 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
Is there a simple way?
Upvotes: 1
Views: 280
Reputation: 51
this is my answer for 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']]}}}
]))
Upvotes: 1