1

Clojure の Mongerライブラリを使用して MongeoDB データベースに接続しています。

Mongo データベースでサブドキュメントを更新、挿入、および削除したいと考えています。MongoDB の $push 修飾子を使用すると、検索したドキュメントのルートでこれを行うことができます。しかし、サブコレクションに $push できるようにしたいです。Monger のテストを見ると、それは可能に見えます。しかし、3 番目の親の子コレクションに確実にプッシュできるようにしたいと考えています。モンガーはこのようなことをすることができますか?

    (mgcol/update mycollection { :my-criteria-key "my-criteria-value" } { $push { "parent.3.child-collection" "fubar" }} )

さらに良いのは、$push に $where 句を含める機能です。このようなことは可能ですか?

    (mgcol/更新 mycollection
          { :doc-criteria-key "doc-criteria-value" }
          { $プッシュ
              { { $where { 親.子.姓: 'スミス' } }
              "フバー" } }
    )

しかし、基本的なレベルでも、repl で次のコマンドを実行すると、以下のエラーが発生します。

  1. 「fubar」データベースは確かに存在します

  2. 私は間違いなくDBに接続しています

  3. { :owner "fubar@gmail.com" }基準は間違いなく有効です。と

  4. "content.1.content"私は両方を試しました"content.$.content"

    repl => (mc/update "fubar" { :owner "fubar@gmail.com" } { $push { "content.1.content" { "fu" "bar" } } } )
    ClassCastException clojure.lang.Var$Unbound は com.mongodb.DB monger.collection/update にキャストできません (collection.clj:310)
    交換 =>
    交換 =>
    repl => (clojure.repl/pst *e)
    ClassCastException clojure.lang.Var$Unbound は com.mongodb.DB にキャストできません
            monger.collection/update (collection.clj:310)
            bkell.run.run-ring/eval2254 (NO_SOURCE_FILE:46)
            clojure.lang.Compiler.eval (Compiler.java:6406)
            clojure.lang.Compiler.eval (Compiler.java:6372)
            clojure.core/eval (core.clj:2745)
            clojure.main/repl/read-eval-print--6016 (main.clj:244)
            clojure.main/repl/fn--6021 (main.clj:265)
            clojure.main/repl (main.clj:265)
            user/eval27/acc--3869--auto----30/fn--32 (NO_SOURCE_FILE:1)
            java.lang.Thread.run (Thread.java:619)

誰かがこれに遭遇して解決しましたか?

ありがとう

4

1 に答える 1

2

説明にいくつかの矛盾と穴がある 3 つの部分からなる質問があります。これが私の最善の推測です。近いことを願っています。

更新リクエストに一致するスキーマがあれば、3 つすべてを動作させることができます。詳細については、以下の test/core.clj を参照してください。

最初の部分: はい、あなたが書いたように、3 番目の親の子コレクションにプッシュできます。

2 番目の部分: 「$where」句を条件に移動し、objNew で $ を使用します。

3 番目の部分: はい、基本的な更新は、あなたが書いたとおりに機能します。

一番下に「lein test」の出力が続きます。あなたの努力に最善を尽くします。

test/core.clj

(ns free-11749-clojure-subdoc.test.core
  (:use [free-11749-clojure-subdoc.core])
  (:use [clojure.test])
  (:require [monger.core :as mg] [monger.collection :as mgcol] [monger.query])
  (:use [monger.operators])
  (:import [org.bson.types ObjectId] [com.mongodb DB WriteConcern]))

(deftest monger-sub-document

    (mg/connect!)
    (mg/set-db! (mg/get-db "test"))

    (def mycollection "free11749")

    ;; first part
    (mgcol/remove mycollection)
    (is (= 0 (mgcol/count mycollection)))

    (def doc1 {
        :my-criteria-key "my-criteria-value"
        :parent [
                { :child-collection [ "cc0" ] }
                { :child-collection [ "cc1" ] }
                { :child-collection [ "cc2" ] }
                { :child-collection [ "cc3" ] }
                { :child-collection [ "cc4" ] }
            ]
        }
    )

    (mgcol/insert mycollection doc1)
    (is (= 1 (mgcol/count mycollection)))

    (mgcol/update mycollection { :my-criteria-key "my-criteria-value" } { $push { "parent.3.child-collection" "fubar" }} )

    (def mymap1 (first (mgcol/find-maps mycollection { :my-criteria-key "my-criteria-value" })))
    (is (= "fubar" (peek (:child-collection (get (:parent mymap1) 3)))))

    (prn (mgcol/find-maps mycollection { :my-criteria-key "my-criteria-value" }))


    ;; second part
    (mgcol/remove mycollection)
    (is (= 0 (mgcol/count mycollection)))

    (def doc2 {
        :doc-criteria-key "doc-criteria-value"
        :parent [
                    { :child  { :lastname [ "Alias" ] } }
                    { :child  { :lastname [ "Smith" ] } }
                    { :child  { :lastname [ "Jones" ] } }
                ]
        }
    )

    (mgcol/insert mycollection doc2)
    (is (= 1 (mgcol/count mycollection)))

    (mgcol/update mycollection { :doc-criteria-key "doc-criteria-value" "parent.child.lastname" "Smith"} { $push { :parent.$.child.lastname "fubar" } } )

    (def mymap2 (first (mgcol/find-maps mycollection { :doc-criteria-key "doc-criteria-value" })))
    (is (= "fubar" (peek (:lastname (:child (get (:parent mymap2) 1))))))

    (prn (mgcol/find-maps mycollection { :doc-criteria-key "doc-criteria-value" }))

    ;; third part
    (mgcol/remove "fubar")
    (is (= 0 (mgcol/count "fubar")))

    (def doc3 {
            :owner "fubar@gmail.com"
            :content [
                    { :content [ "cc0" ] }
                    { :content [ "cc1" ] }
                    { :content [ "cc2" ] }
            ]
        }
    )

    (mgcol/insert "fubar" doc3)
    (is (= 1 (mgcol/count "fubar")))

    (mgcol/update "fubar" { :owner "fubar@gmail.com" } { $push { "content.1.content" { "fu" "bar" } } } )

    (def mymap3 (first (mgcol/find-maps "fubar" { :owner "fubar@gmail.com" })))
    (is (= { :fu "bar" } (peek (:content (get (:content mymap3) 1)))))

    (prn (mgcol/find-maps "fubar" { :owner "fubar@gmail.com" }))
)

レインテスト

Testing free-11749-clojure-subdoc.test.core
({:_id #<ObjectId 4fb3e98447281968f7d42cac>, :my-criteria-key "my-criteria-value", :parent [{:child-collection ["cc0"]} {:child-collection ["cc1"]} {:child-collection ["cc2"]} {:child-collection ["cc3" "fubar"]} {:child-collection ["cc4"]}]})
({:_id #<ObjectId 4fb3e98447281968f7d42cad>, :doc-criteria-key "doc-criteria-value", :parent [{:child {:lastname ["Alias"]}} {:child {:lastname ["Smith" "fubar"]}} {:child {:lastname ["Jones"]}}]})
({:_id #<ObjectId 4fb3e98447281968f7d42cae>, :content [{:content ["cc0"]} {:content ["cc1" {:fu "bar"}]} {:content ["cc2"]}], :owner "fubar@gmail.com"})

Ran 1 tests containing 9 assertions.
0 failures, 0 errors.
于 2012-05-16T17:59:09.120 に答える