2013-01-15 103 views
4

標題可能不是超清晰,這裏春數據MongoDB的查詢字符串轉換爲自動OBJECTID

我以這種形式執行的更新問題:

db.poi.update({ 
    _id: ObjectId("50f40cd052187a491707053b"), 
    "votes.userid": { 
    "$ne": "50f5460d5218fe9d1e2c7b4f" 
    } 
}, 
{ 
    $push: { 
    votes: { 
     "userid": "50f5460d5218fe9d1e2c7b4f", 
     "value": 1 
    } 
    }, 
    $inc: { "score":1 } 
}) 

要在插入文件數組中只有當沒有一個具有相同的userid時(解決方法是因爲唯一索引不適用於數組)。該代碼從mongo控制檯正常工作。從我的應用程序正在使用此:

@Override 
public void vote(String id, Vote vote) { 
    Query query = new Query(Criteria.where("_id").is(id).and("votes.userid").ne(vote.getUserid())); 
    Update update = new Update().inc("score", vote.getValue()).push("votes", vote); 
    mongoOperations.updateFirst(query, update, Poi.class); 
} 

此工作正常,如果爲「用戶id」我用一個String,不能是蒙戈的ObjectId,但如果我用字符串中的示例中,查詢執行這樣翻譯(來自mongosniff):

update flags:0 q:{ _id: ObjectId('50f40cd052187a491707053b'), votes.userid: { $ne: ObjectId('50f5460d5218fe9d1e2c7b4f') } } o:{ $inc: { score: 1 }, $push: { votes: { userid: "50f5460d5218fe9d1e2c7b4f", value: 1 } } } 

該字符串現在是一個Objectid。這是一個錯誤? BasicQuery做同樣的事情。我看到的唯一的其他解決方案是對所有類ID使用ObjectId而不是String。

有什麼想法?

UPDATE:

這是投票類

public class Vote { 
    private String userid; 
    private int value; 
} 

這是User類

@Document 
public class User { 

    @Id 
    private String id; 
    private String username; 
} 

這是類和蒙戈文件在那裏我做這個更新

@Document 
public class MyClass { 

    @Id 
    private String id; 
    @Indexed 
    private String name; 
    int score 
    private Set<Vote>votes = new HashSet<Vote>(); 
} 

爲JSON在votes.userid

{ 
    "_id" : ObjectId("50f40cd052187a491707053b"), 
    "name" : "Test", 
    "score" : 12, 
    "votes" : [ 
    { 
     "userid" : "50f5460d5218fe9d1e2c7b4f", 
     "value" : 1 
    } 
    ] 
} 

用戶ID被推爲字符串,但相同的字符串比較作爲的ObjectId在$ NE

+0

看來你存儲'String'值,可以是'ObjectId's內部。這是什麼原因? 'String'到''ObjectId'的轉換目前可以在你的Java對象中使用'String',並且在數據庫中仍然有ObjectId。 –

+0

也許我錯過了一些東西。我將字符串用作用戶對象的_id;我的Vote對象有一個userid String字段,我用它作爲用戶_id的參考。數據庫中的投票「字段」是一組文檔。當我在這個數組中推送一個vote.userid時,我在數據庫中有一個字符串,而不是一個ObjectId。我會用一些代碼更新我的帖子,使其更加清晰。 – alex

+0

你不會說你使用的是Spring-data-mongodb的版本。當從1.0.3升級到1.1.0時,我最近被這個反過來咬了,因爲它們似乎已經取消了這種自動轉換。我被咬了,因爲我導出爲JSON,然後重新導入,留下「_id」:{「$ id」:「4ee76418f3e1450f11000000」},這給了我org.springframework.data.mapping.model.MappingException:No映射爲java.lang.String找到的元數據。我不認爲你可以兩種方式 –

回答

2

在我看來,這個問題可以這樣描述:如果您在類中使用String來代替ObjectId,如果您想在其他文檔(和嵌入文檔)中使用這些id作爲引用(no dbrefs),它們會以String的形式推送(因爲它們是Strings)。這很好,因爲spring數據可以將它們映射到objectid,但如果您執行像我提到的那樣的查詢,那就不好了;該字段在比較中轉換爲objectid(本例中爲$ ne操作符),但在嵌入式文檔中被視爲字符串。所以,總結一下,在我看來,這種情況下的$ ne操作符應該將字段視爲String。

我的解決辦法是寫一個自定義轉換到字符串存儲爲在ID是一個參考文檔的OBJECTID

public class VoteWriteConverter implements Converter<Vote, DBObject> { 

    @Override 
    public DBObject convert(Vote vote) { 
    DBObject dbo = new BasicDBObject(); 
    dbo.put("userid", new ObjectId(vote.getUserid())); 
    dbo.put("value", vote.getValue()); 
    return dbo; 
    } 
} 
相關問題