10

Assume that I have such entities like the following:

@Document(collection = "doc_a")
public class A {    
  @Field("id")
  private Integer id;

  @Field("b")
  private Collection<B> b;
  ...
}


public class B {    
  @Field("id")
  private Integer id;
  ...
}

is it possible to use a compoundIndex with respect to A.id AND B.id together?

I mean maybe like:

@CompoundIndex(name = "aid_bid_idx", def = "{'id', 'b.id'}")

Thanks in advance.

javatar
  • 4,542
  • 14
  • 50
  • 67
  • have you tried it? It doesn't work? – Miguel Cartagena Dec 27 '12 at 01:28
  • I haven't tried yet, in our environment it is quite hard to understand whether indexes are created and working successfully or not. Mongodb responsibility is owned by our architect, and nowadays he is not available. That's why I wanted to ask first from here. – javatar Dec 27 '12 at 08:37

3 Answers3

20

I've tried this kind of compound index in my app, that use spring data too, and worked properly. You only have to correct the index definition in @CompoundIndex annotation:

@CompoundIndex(name = "aid_bid_idx", def = "{'id' : 1, 'b.id' : 1}")
@Document(collection = "doc_a")
public class A {    
  @Field("id")
  private Integer id;

  @Field("b")
  private Collection<B> b;
  ...
}

public class B {    
  @Field("id")
  private Integer id;
  ...
} 

If you run a query with explain (like the follows) in mongo shell, you'll see that the index *aid_bid_idx* will be used.

db.doc_a.find({ "id" : 1, "b.id" : 1}).explain()

The result will be something like this:

{
    "cursor" : "BtreeCursor aid_bid_idx",
    ...
}
Miguel Cartagena
  • 2,576
  • 17
  • 20
3

I had the same problem, for me the Miguel's solution worked but I had to wrap the @CompoundIndex inside a @CompoundIndexes otherwise it didn't work (I'm using Spring Roo).

@CompoundIndexes({
    @CompoundIndex(name = "aid_bid_idx", def = "{'id' : 1, 'b.id' : 1}")
})
@Document(collection = "doc_a")
public class A {...}
madx
  • 6,723
  • 4
  • 55
  • 59
  • 2
    I think CompounIndex directly will also work. One thing that was missing in the documentation is they fail to mention when the indexes will be created post introducing them in the code block. After playing around it for a while, i see that indexes are getting created only after inserting a new document post introducing them in the code. – Biscuit Coder Mar 31 '17 at 07:49
  • it doesn't work with only single `CompoundIndex` – soyphea Nov 09 '21 at 09:35
0

@CompoundIndexes({ @CompoundIndex(name = "aid_bid_idx", def = "{'id' : 1, 'b.id' : 1}") }) @Document(collection = "doc_a") public class A {...}

In this snippet, it's better to have the value attribute for the @CompoundIndexes annotation and if it's unique, then mark it as unique=true. Such as, along with the usage of lombok:

@Data
@CompoundIndexes(value = {
   @CompoundIndex(name = "aid_bid_idx", def = "{'id' : 1, 'b.id' : 1}", unique = true)}) 
@Document(collection = "doc_a") 
public class A {...implementation...}
Sanjay
  • 1