2013-04-04 15 views
10

Ich benutze spring-data-mongodb-1.2.0.RELEASE. Ich habe zwei Klassen A und B, wo B einen Verweis auf A hat und es mit @DBRef annotiert ist.Spring Data - MongoDB Indexierung DBRef

Klasse A:

@Document(collection = "a") 
public class A { 
@Id 
public String id; 

/** The TicketGrantingTicket this is associated with. */ 
@Field 
public String name; 

public A(String id, String name) { 
    this.id = id; 
    this.name = name; 
} 
} 

Klasse B:

@Document(collection = "b") 
public class B { 

@Id 
public String id; 

@Field 
public String name; 

@DBRef 
@Indexed 
public A a; 

public B(String id, String name, A a) { 
    super(); 
    this.id = id; 
    this.name = name; 
    this.a = a; 
} 
} 

Da ich für alle Fälle von B Quering, die zu einem bestimmten A sich beziehen:

B fromDB = mongoOperations.findOne(Query.query(Criteria.where("a.$id").is(a1.id)), B.class); 

I muss es indiziert werden.

Nach dem ersten Einfügen einer B-Instanz in MongoDB sollte ein Index erstellt werden. Wie unten zu sehen ist:

Weiß jemand, wie ich einen solchen Index erstellen kann?

Außerdem sieht es so aus, als ob das DBRef-Feld (wie von der Mongo-Shell erkannt wird) nicht mit dem Format übereinstimmt, wie es unter definiert ist.

Fehle ich hier etwas?

Antwort

9

Sie den Index mit der Mongo Shell erstellen kann, aber wenn Sie wollen dies tun es durch Code und da Sie Feder-data-mongodb verwenden, verwenden:

mongoTemplate.indexOps(B.class).ensureIndex(new Index().on("a", Order.ASCENDING));

Sie können auch die n angeben ame der Sammlung, wenn der Name der Klasse ist es nicht übereinstimmen:

mongoTemplate.indexOps("b").ensureIndex(new Index().on("a", Order.ASCENDING)); 
5

Ich denke, das funktioniert: @CompoundIndex(name = "b_ref_to_a", def = "{'a.id' : 1}") @Document(collection = "b") public class B {...}

Wenn nicht, Sie mongoTemplate.indexOps("b").ensureIndex(...) in einem Verfahren mit Anmerkungen versehen mit @PostConstruct anrufen oder so

+1

Dankten für die Hilfe. Warum wird der Index nicht erstellt, obwohl er mit @Indexed versehen ist? und eine andere offene Frage ist, warum MongoDB Dokumentation zeigt die DBRef in einem anderen Format als das, das in der Mongo-Shell-Snapshot gesehen werden kann – Modi

+0

Wie für die @Indexed, es ist nicht wirklich dokumentiert, aber ich denke nicht, dass es für komplexe geeignet ist Typen, hat sowieso nie für mich gearbeitet. Persönlich verwende ich eine der beiden oben genannten Methoden, um den "komplexen" Typ zu indizieren. Wie für die zweite Ausgabe, welche Version von mongodb Shell verwendest du? versuche 'db.d.find ({}, {" a. $ ref ": 1," a. $ id ": 1})' was bekommst du? –

+0

Ich benutze Mongo DB und Shell-Version 2.4.1. Ich bin in der Lage, die nächsten Abfragen auszuführen: db.b.find ({"a. $ Id": }, {"a. $ Id": 1}) und db.b.find ({"a. $ id ": }, {" a. $ ref ": 1}) aber Ich kann keine. $ ref und a. $ ID für das Projektionsargument einschließen und das Bedingungsargument muss" a. $ id "enthalten. Am wichtigsten ist, dass das Abfrageelement die a. $ Id und a. $ Ref: db.b enthalten muss, um den Index zu verwenden, der für 'a' erstellt wurde.find ({a: {"$ ref": a, "$ id": }}) – Modi

3

ich hatte das gleiche Problem, für mich die Lösung des ORID gearbeitet, aber ich hatte das @CompoundIndex innerhalb eines @CompoundIndexes wickeln sonst es didn Ich arbeite nicht (ich benutze Spring Roo).

@CompoundIndexes({ 
    @CompoundIndex(name = "b_ref_to_a", def = "{'a.id' : 1}") 
}) 
@Document(collection = "b") 
public class B {...} 
1
DBObject indexOptions = new BasicDBObject(); 
indexOptions.put("a", 1); 
indexOptions.put("b", 1); 
indexOptions.put("c.d", 1); 
indexOptions.put("e.f", 1); 
CompoundIndexDefinition indexDefinition = 
      new CompoundIndexDefinition(indexOptions); 
mongoTemplate.indexOps(.class).ensureIndex(indexDefinition); 

for unique index you can add mongoTemplate.indexOps(.class).ensureIndex(indexDefinition).unique();