如何忽略mongodb中的一个键?

时间:2014-12-16 17:40:40

标签: python mongodb

我怎能不关心p1p2

我永远不会关心玩家本身是玩家1还是玩家2。 我所关心的只是他们在一场比赛中相互比赛。

我有这种格式的文件,它代表比赛中的一场比赛:

{u'_id': ObjectId('5490690b2e8738094b2f8753'),
 u'date': u'2014-08-02',
 u'game': 7,
 u'players': {u'p1': {u'char': u'marth',
                      u'name': u'jack',
                      u'stocks': {u'stock1': {u'dmg': 133, u'time': 89},
                                  u'stock2': {u'dmg': False,
                                              u'time': False},
                                  u'stock3': {u'dmg': False,
                                              u'time': False},
                                  u'stock4': {u'dmg': False,
                                              u'time': False}}},
              u'p2': {u'char': u'fox',
                      u'name': u'ben',
                      u'stocks': {u'stock1': {u'dmg': 45, u'time': 15},
                                  u'stock2': {u'dmg': 77, u'time': 35},
                                  u'stock3': {u'dmg': 102, u'time': 78},
                                  u'stock4': {u'dmg': 80, u'time': 120}}}},
 u'stage': u'bf',
 u'tournament': u'King of Kings 2014'}

我想通过name'ben'找到所有涉及玩家的游戏;如果他是p1p2则无关紧要。 我只知道我可以这样做:

db.games.aggregate([{'$project' : {'players.p1.name': 1}},
    {'$group': {'_id' : '$players.p1.name', 'count': {'$sum': 1}}}])

输出:

{u'ok': 1.0,
 u'result': [{u'_id': u'ben', u'count': 4},
             {u'_id': u'man', u'count': 21},
             {u'_id': u'hammy', u'count': 5},
             {u'_id': u'left', u'count': 9},
             {u'_id': u'armed', u'count': 12},
             {u'_id': u'icicle', u'count': 11},
             {u'_id': u'2king', u'count': 45},
             {u'_id': u'strangelove', u'count': 9},
             {u'_id': u'jack', u'count': 16}]}

但它只给了我p1。正如我之前所说,我实际上并不关心他们是什么球员。

您能否告诉我是否应该更改我的数据结构(架构?),以便我可以轻松有效地执行这些类型的查找。

我尝试将播放器放入players数组(没有p1 / p2个键,但这似乎会让其他查询变得更难。)

所以我不确定在这种情况下最好的策略是什么......

2 个答案:

答案 0 :(得分:0)

最简单的方法是在阵列中添加玩家。

{
    "_id" : ...
    ...
    "ps" : ["jack", "ben"]
    ...
}

要查找杰克所玩的所有比赛,

db.games.find({ "ps" : "jack" })

在我看来,如果每个玩家都是长度为2的数组中的对象,你就会拥有更自然的结构,并且你可以进行类似上面的查询来查找涉及给定玩家的所有匹配,但是你说这使得其他查询更加困难。你没有说出那些查询是什么,所以我无法帮助你,但是添加一个只有名字的额外数组应该有所帮助。

答案 1 :(得分:0)

如果你不想改变文档的结构,那么使用Python的MongoDB API怎么样?

import pymongo

db = pymongo.MongoClient()
document = db.my.collection.find({},{"_id":0})

names = []

for document in documents:
    for players in document['players']:
       names.append(document['players'][players]['name'])

for name in set(names):
   print "{0}:{1}".format(name, names.count(name))

您可以将结果分配给列表或字典,而不是“打印”。