使用spring data mongodb删除对象中的数组条目

时间:2012-08-21 11:46:08

标签: mongodb spring-data

我最近花了一些时间尝试通过Spring的Data MongoOperations接口使用$pull运算符,所以我认为如果有人碰到类似的问题,分享我的发现会很好。

所以这就是......

我有两个java POJO:

@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运算符来删除名为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()时,我没有收到任何错误。数据库中没有完成更新。

我知道类似的问题已经被问到here但是给出的答案并没有使用MongoOperations接口。

5 个答案:

答案 0 :(得分:4)

在搜索了一下并查看源代码后,我意识到我需要将一个InnerDocument对象作为第二个参数传递给pull方法,以便spring类能够正确地进行映射。

事实证明我可以在选择对象时导航对象(我在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());

答案 1 :(得分:1)

您也可以使用BasicDBObject而不是我意外发现的InnerDocument。通过打印出更新对象,您可以看到实际的mongo shell查询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"}}}

答案 2 :(得分:0)

我尝试了med116给出的解决方案,但必须对其进行修改才能起作用:

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

因为否则我的数组中没有匹配的对象。

答案 3 :(得分:0)

在春季数据mongo中,就像这样:


//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);

答案 4 :(得分:0)

如果您只是想从数组中删除一个没有任何其他属性(如名称)的元素,请编写您希望的查询并

Update update = new Update();
update.pull("Yourarrayname","valueyouwishtodelete");  
mongoTemplate.upsert(query,update,"collectionname");