1

3 日前に MongoDB の学習を開始しましたが、演習を行っているときに、サーバーから予期しない動作が発生しました。

この演習では、次の構造を持つドキュメントから宿題のスコアが最も低いものを削除する小さなプログラムを作成するよう求められました (このドキュメントは students コレクション内にあります)。

{
    "_id": 10,
    "name": "Demarcus Audette",
    "scores": [
        {
            "type": "exam"
            "score": 47.42086

        },
        {
            "type": "quiz"
            "score": 44.83456

        },{
            "type": "homework"
            "score": 39.0178956

        },{
            "type": "homework"
            "score": 14.578344

        }
    ]
}

とにかく、プログラムを書いているときに、うっかりミスをしてしまいました。ここに私が書いたプログラムがあります

def removeHW(hw):
    # establish a connection to the database
    connection = MongoClient("localhost", 27017)

    # get a handle to the school database
    db = connection.school
    students = db.students

    # extract the scores into a list
    scores = []
    for i in range(1, len(hw)):
        scores.append(hw[i]["score"])

    # Now remove the lowest score from the database
    query = {"_id": hw[0], "scores.score": min(scores),"scores.type": "homework"}

    try:
        students.remove(query)
    except: 
        print "Unexpected error:", sys.exc_info()[0]

このプログラムの背後にあるロジックは、生徒のコレクションから 2 つの宿題と _id を含む辞書のリストを抽出した後、すべての辞書を繰り返し処理し、それを removeHW() 関数に渡すというものです。

私が犯した間違いは、私が書いたことです:

query = {"_id": hw[0], "scores.score": min(scores),"scores.type": "homework"}
students.remove(query)

次のように書くべきだったとき(これは正しい解決策です):

query = {"_id": hw[0], "scores.type": "homework"}
students.update(query, {"$pull": {"scores": {"score" : min(scores)}}})

はい、私は今まですべてが大丈夫だと思っていました。私が遭遇した問題は、最初の解決策 (間違った解決策) を使用したときに、MongoDB が 学生コレクションからすべてのドキュメントを削除し、削除したいものを除いて学生コレクションからすべてのサブドキュメントを含む新しいコレクションスコアを作成したことです (最下位)。私はこの動作が非常に奇妙であることに気付きました。NoSQL データベースの経験がないので、MongoDB がそれを行う原因とその理由を知りたいです。

誰かが私を理解するのを手伝ってくれるなら、してください。末永くよろしくお願いいたします。

4

2 に答える 2

1

特定の学生のすべてのデータが同じドキュメントに保存されているため、動作は完全に正常です。何が起こっているかというと、コレクションの各ドキュメントには、タイプの宿題の評価の最小スコアがあります。したがって、各ドキュメントは条件に一致し、削除されます。

2 番目のオプションでは、スコアを 1 つ引くという予防策を講じます。それでも、常に成功するとは限りません。小テストまたは試験のスコアが、宿題の最小スコアに等しいとします。それを引くこともできます。最小スコアで評価を取得していることを確認するだけでなく、取得している評価が宿題のタイプであることも確認する必要があります。

クエリの一部 ("scores.type": "homework") は、宿題で少なくとも 1 つのスコアを持つ生徒のみを更新することを確認するだけです。宿題がない生徒がいる場合、min; に問題がある可能性があります。私はパイソンに精通していません。

于 2013-07-05T22:58:56.107 に答える