-->

MongoDB Composite Key

2020-01-29 04:49发布

问题:

I'm just getting started with MongoDb and I've noticed that I get a lot of duplicate records for entries that I meant to be unique. I would like to know how to use a composite key for my data and I'm looking for information on how to create them. Lastly, I am using Java to access mongo and morphia as my ORM layer so including those in your answers would be awesome.

Morphia: http://code.google.com/p/morphia/

回答1:

You can use objects for the _id field as well. The _id field is always unique. That way you kind of get a composite primary key:

 { _id : { a : 1, b: 1} }

Just be careful when creating these ids that the order of keys (a and b in the example) matters, if you swap them around, it is considered a different object.

The other possibility is to leave _id alone and create a unique compound index.

db.things.ensureIndex({firstname: 1, lastname: 1}, {unique: true});
//Deprecated since version 3.0.0, is now an alias for db.things.createIndex()

https://docs.mongodb.org/v3.0/reference/method/db.collection.ensureIndex/



回答2:

You can create Unique Indexes on the fields of the document that you'd want to test uniqueness on. They can be composite as well (called compound key indexes in MongoDB land), as you can see from the documentation. Morphia does have a @Indexed annotation to support indexing at the field level. In addition with morphia you can define compound keys at the class level with the @Indexed annotation.



回答3:

I just noticed that the question is marked as "java", so you'd want to do something like:

final BasicDBObject id = new BasicDBObject("a", aVal)
        .append("b", bVal)
        .append("c", cVal);
results = coll.find(new BasicDBObjet("_id", id));

I use Morphia too, but have found (that while it works) it generates lots of errors as it tries to marshall the composite key. I use the above when querying to avoid these errors.

My original code (which also works):

final ProbId key = new ProbId(srcText, srcLang, destLang);
final QueryImpl<Probabilities> query = ds.createQuery(Probabilities.class)
  .field("id").equal(key);
Probabilities probs = (Probabilities) query.get();

My ProbId class is annotated as @Entity(noClassnameStored = true) and inside the Probabilities class, the id field is @Id ProbId id;