使用外键查询时MongoDB的奇怪行为

时间:2014-05-07 11:48:38

标签: java spring mongodb

我正在编写一些测试代码来学习MongoDB的spring-data。我可以成功创建两个文档:Person和ADocument,其中ADocument包含对Person的引用。

@Document
public class Person {

@Id
private ObjectId id;
@Indexed
private String name;

public ObjectId getId() {
    return id;
}

public void setId(ObjectId id) {
    this.id = id;
}

public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}

}

...

@Document
public class ADocument {

@Id
private ObjectId id;

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public String getText() {
    return text;
}

public void setText(String text) {
    this.text = text;
}

private String title;
private String text;

@DBRef
private Person docperson;


public Person getDocperson() {
    return docperson;
}

public void setDocperson(Person docperson) {
    this.docperson = docperson;
}

public ObjectId getId() {
    return id;
}

public void setId(ObjectId id) {
    this.id = id;
}

}

当我尝试通过使用此人的ID(一旦提供此人的姓名)获取与某人相关的所有“附件”时,就会出现问题:

    public List<ADocument> loadDocumentsByPersonName(String pname) {
    Query qPerson = new Query().addCriteria(Criteria.where("name").is(pname));
    qPerson.fields().include("_id");
    Person pers = mongoTemplate.findOne(qPerson, Person.class);
    ObjectId persId = pers.getId();
    Query qDoc = new Query().addCriteria(Criteria.where("person.$id").is(persId));
    System.out.println(qDoc.toString());
    List<ADocument> list2 = mongoTemplate.find(qDoc, ADocument.class);
    return list2;
}

除了list2始终为空(但不应该)之外,其他工作正常。 System.out.println(qDoc.toString())给出了类似的内容:

查询:{“person。$ id”:{“$ oid”:“536a0d50e4b0d0c10297f2ab”}},字段:null,排序:null

如果我尝试在Mongo shell上发出上面的查询,我会得到以下内容:

  

db.adocument.find({“person。$ id”:{“$ oid”:“536a0805e4b0af174d0b5871”}})

error: {
"$err" : "Can't canonicalize query: BadValue unknown operator: $oid",
"code" : 17287
}

如果我输入

  

db.adocument.find({“person。$ id”:ObjectId(“536a0805e4b0af174d0b5871”)})

我实际上得到了一个结果!

我正在使用MongoDB 2.6.0和Spring Data 1.4.2。

我真的无法弄清楚发生了什么......非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

我明白了! 出于某种原因,我必须在Query中显式收集名称: List list2 = mongoTemplate.find(qDoc,ADocument.class,COLLECTION_NAME); COLLECTION_NAME =“adocument”。

对于shell行为,似乎Query.toString()永远不会返回正确的语法来进行剪切和粘贴以便执行shell。