5

私は最近、$pullSpringのData MongoOperationsインターフェースを介してオペレーターを使用しようとしばらく時間を費やしたので、誰かが同様の問題に遭遇した場合に備えて、私の調査結果を共有するとよいと思いました。

だからここに行く...

私はそのような2つのJavaPOJOを持っています:

@Document
public class OutterObject{

    private String id;
    private String name;
    private List<InnerDocument> innerDocs;


    //SETTERS - GETTERS Ommited


public class InnerDocument{


    private String id;
    private String name;

         //SETTERS - GETTERS Ommited

これは次のようにMongoコレクションに保存されます:

 "_id" : "doc2",
 "_class" : "OutterObject",
 "name" : "doc2",
 "innerDocs" : [{
      "_id" : "innerDoc21",
      "name" : "innerDoc21"
  }, {
      "_id" : "innerDoc22",
      "name" : "innerDoc22"
  }]

$ pull演算子を使用して、name value="innerDoc22"を持つinnerDocコレクション内のすべてのオブジェクトを削除しようとしています。

私はこのようにmongoドライバーを使用してこれを達成する方法を知っています:

 List<String> ids = 
         Arrays.asList("innerDoc22");

 BasicDBObject find = new BasicDBObject();

 match.put("innerDocs.name", 
           BasicDBObjectBuilder.start("$in", ids).get());

    BasicDBObject update = new BasicDBObject();
        update.put(
                "$pull",
                BasicDBObjectBuilder.start("innerDocs",
                        BasicDBObjectBuilder.start("name", "innerDoc22").get()).get());

  DBCollection col= mongoOperations.getDb().getCollection("outterObject");

  col.update(find , update);

SpringのMongoOperationsインターフェイスを使用して同じことを達成しようとしています。これがMongoOperationsインターフェースを使用した私のコードです:

List<String> ids = Arrays.asList("innerDoc22");

Query removeQuery = Query.query(Criteria.where("innerDocs.name").in(ids));

WriteResult wc = mongoOperations.upsert(
                    removeQuery, 
                    new Update().pull("innerDocs.name", "innerDoc22"), 
                    OutterObject.class);
System.out.println(wc.getLastError());

更新の呼び出しgetLastError()がデータベースで行われていないだけでも、エラーは発生しません。

同様の質問がすでにここで行われていることは知っていますが、与えられた回答はMongoOperationsインターフェイスを使用していません。

4

7 に答える 7

5

少し検索してソースコードを調べた後、Springクラスが正しくマッピングを実行できるように、2番目のパラメーターとしてInnerDocumentオブジェクトをpullメソッドに渡す必要があることに気付きました。

結局のところ、オブジェクトを選択しながらオブジェクトをナビゲートすることはできますが(removeQueryで「innerDocs.name」を使用しています)、ドキュメントを更新するときに同じことを行うことはできません(または方法が見つかりませんでした)。

以下は、MongoOperationsを使用してクエリを実装した方法です。

List<String> ids = Arrays.asList("innerDoc22", "innerDoc21");

Query removeQuery = Query.query(Criteria.where("innerDocs.name").in(ids));

WriteResult wc = 
       mongoOperations.upsert(removeQuery, 
           new Update().pull("innerDocs", 
           new InnerDocument("innerDoc22", null)), 
           OutterObject.class);

System.out.println(wc.getLastError());
于 2012-08-21T11:46:08.437 に答える
2

偶然見つけたInnerDocumentの代わりにBasicDBObjectを使用することもできます。更新オブジェクトを出力すると、実際のmongoシェルクエリjsonを確認できます。これは、デバッグに非常に役立ちます。:

Update updateObj = new Update()
         .pull("innerDocs", new BasicDBObject("innerDocs.name","innerDoc22"));

System.out.println("UPDATE OBJ: " + updateObj.toString());

結果:

UPDATE OBJ: { "$pull" : { "innerDocs" : { "innerDocs.name" : "innerDoc22"}}}

于 2016-05-20T11:40:12.270 に答える
2

私はmed116によって与えられた解決策を試しました、そして私はそれを機能するように修正しなければなりませんでした:

Update updateObj = new Update().pull("innerDocs", new BasicDBObject("name","innerDoc22"));

そうでなければ、私の配列に一致するオブジェクトがなかったからです。

于 2018-10-30T07:51:42.740 に答える
0

春のデータモンゴでは、次のようになります。


//remove array's one elem
UpdateResult wc = mongoTemplate.upsert(removeQuery,new Update().pull("tags",Query.query(Criteria.where("tag").is("java"))),TestPull.class);
//remove array's multi-elem
UpdateResult wc1 = mongoTemplate.upsert(removeQuery,new Update().pull("tags",Query.query(Criteria.where("tag").in(Arrays.asList("mongo", "netty")))),TestPull.class);
于 2018-12-30T09:13:44.063 に答える
0

nameのような他のプロパティを持たない要素を配列から削除したいだけの場合は、必要なクエリを記述して、

Update update = new Update();
update.pull("Yourarrayname","valueyouwishtodelete");  
mongoTemplate.upsert(query,update,"collectionname");
于 2021-04-27T18:25:39.660 に答える
0

それが私の解決策です-@ufasoliに感謝します:

  public Mono<ProjectChild> DeleteCritTemplChild(String id, String idch) {
    Query query = new Query();
    query.addCriteria(Criteria
                           .where("_id")
                           .is(id)
                           .and("tasks._id")
                           .is(idch)
                     );

    Update update = new Update();
    update.set("tasks.$", null);

    return template
         // findAndModify:
         // Find/modify/get the "new object" from a single operation.
         .findAndModify(
              query, update,
              new FindAndModifyOptions().returnNew(true), ProjectChild.class
                       );
  }
于 2021-12-23T21:12:30.160 に答える
0

これは私のために働きます!

UpdateResult updateResult = mongoTemplate.updateMulti(new Query(where("id").is(activity.getId())), new Update().pull("comments", new Query(where("id").is(commentId))), Activity.class);

それは生成します:

Calling update using query: { "_id" : { "$oid" : "61f900e7c7b79442eb3855ea"}} and update: { "$pull" : { "comments" : { "_id" : "61fac32e3f9ab5646e016bc8"}}} in collection: activity
于 2022-02-02T18:23:29.863 に答える