如何编写更新嵌入式文档的查询

时间:2015-05-27 12:47:18

标签: java mongodb spring-boot spring-data-mongodb

我刚接触spring数据mongodb,但我只是坚持,如何使用mongo存储库为嵌入式文档编写基于json的查询。

我的数据库看起来像

"_id" : ObjectId("5565ad670cf25cbd975ab2d9"),
    "_class" : "com.samepinch.domain.metadata.Metadata",
    "preferenceType" : "shopping",
    "subtypes" : [
        {
            "_id" : ObjectId("5565ad670cf25cbd975ab2d2"),
            "subType" : "veg",
            "preferencePoint" : 0
        },
        {
            "_id" : null,
            "subType" : "nonveg",
            "preferencePoint" : 0
        }
    ],
    "createdDate" : ISODate("2015-05-27T11:41:27.357Z"),
    "updatedDate" : ISODate("2015-05-27T11:41:27.357Z")

我想根据顶级文档ID更新子类型,我必须为具有id 5565ad670cf25cbd975ab2d2的子类型更新preferencePoint ,如何为此编写查询?

2 个答案:

答案 0 :(得分:2)

您应该$ projection使用$elemMatch查询,如下所示:

db.collectionName.update({"_id" : ObjectId("5565ad670cf25cbd975ab2d9"),
"subtypes":{"$elemMatch":{"_id":ObjectId("5565ad670cf25cbd975ab2d2")}}},
{"$set":{"subtypes.$.preferencePoint":1}})

及其等效的java代码:

BasicDBObject eleMatch = new BasicDBObject();
eleMatch.put("_id", new ObjectId("5565ad670cf25cbd975ab2d2"));
BasicDBObject elemMatchQuery = new BasicDBObject();
elemMatchQuery.put("$elemMatch", eleMatch);
BasicDBObject query = new BasicDBObject();
query.put("_id", new ObjectId("5565ad670cf25cbd975ab2d9"));
query.put("subtypes", elemMatchQuery);
BasicDBObject set = new BasicDBObject();
set.put("subtypes.$.preferencePoint", 1);
BasicDBObject update = new BasicDBObject();
update.put("$set", set);
DBCollection dbcoll = mongoTemplate.getCollection("collectionName");
DBObject object = dbcoll.update(query, update);

答案 1 :(得分:0)

来自@Query java doc org.springframework.data。 mongodb .repository。查询

  

直接在存储库上声明 finder 查询的注释   方法。这两个属性都允许使用占位符表示法?0,?1   等等。

以下是您可以传递给注释的所有属性(下方)

从定义来看,您似乎只能阅读,过滤特定字段,执行count()或删除与您的查询匹配的域对象。我没有看到有关更新的任何内容。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
@QueryAnnotation
public @interface Query {

    /**
     * Takes a MongoDB JSON string to define the actual query to be executed. This one will take precendece over the
     * method name then.
     * 
     * @return
     */
    String value() default "";

    /**
     * Defines the fields that should be returned for the given query. Note that only these fields will make it into the
     * domain object returned.
     * 
     * @return
     */
    String fields() default "";

    /**
     * Returns whether the query defined should be executed as count projection.
     * 
     * @since 1.3
     * @return
     */
    boolean count() default false;

    /**
     * Returns whether the query should delete matching documents.
     * 
     * @since 1.5
     * @return
     */
    boolean delete() default false;