0

mongo データベースの各ドキュメント/レコードに配列が格納されており、この配列の各要素のスコアを計算し、配列要素の別のフィールドでスコアを集計する必要があります。

私がやろうとしていることを英語で説明するのは難しいので、ここに私がやろうとしていることのpythonの例があります.

records = [
    {"state": "a", "initvalue": 1, "data": [{"time": 1, "value": 2}, {"time": 2, "value": 4}]},
    {"state": "a", "initvalue": 5, "data": [{"time": 1, "value": 7}, {"time": 2, "value": 9}]},
    {"state": "b", "initvalue": 4, "data": [{"time": 1, "value": 2}, {"time": 2, "value": 1}]},
    {"state": "b", "initvalue": 5, "data": [{"time": 1, "value": 3}, {"time": 2, "value": 2}]}
]


def sign(record):
    return 1 if record["state"] == "a" else -1


def score(record):
    return [{"time": element["time"], "score": sign(record) * (element["value"] - record["initvalue"])} for element in record["data"]]

scores = []
for record in records:
    scores += score(record)

sums = {}
for score in scores:
    if score["time"] not in sums:
        sums[score["time"]] = 0
    sums[score["time"]] += score["score"]

print '{:>4} {:>5}'.format('time', 'score')
for time, value in sums.iteritems():
    print '{:>4} {:>5}'.format(time, value)

aこれにより、状態と状態でわずかに異なるスコア関数が計算され、b各時間エントリのスコアが集計されます。

これが結果です

time score
   1     7
   2    13

レコードをPythonに取り込んで集計を再発明することなく、mongoでこれを行う方法を見つけようとしています。

助けてくれてありがとう!

4

1 に答える 1

0

Ok。私はこれを理解しました。パイプラインの仕組みと条件関数について本当に理解したら、すべてがまとまりました。

from pymongo import MongoClient
client = MongoClient()
result = client.mydb.foo.aggregate([
    {'$project': {'_id': 0, 'data': 1, 'initvalue': 1, 'state': 1}},
    {'$unwind':  '$data'},
    {'$project': {
        'time': '$data.time',
        'score': {'$multiply': [
            {'$cond':     [{'$eq': ['$state', 'a']}, 1, -1]},
            {'$subtract': ['$data.value', '$initvalue']}
        ]}
    }},
    {'$group': {
        '_id': '$time',
        'score': {'$sum': '$score'}
    }},
    {'$project': {'_id': 0, 'time': '$_id', 'score': 1}}
])
for record in result['result']:
    print record

これにより、望ましい結果が得られます

{u'score': 13, u'time': 2}
{u'score': 7, u'time': 1}
于 2013-06-19T16:51:56.410 に答える