java - example - spring mongotemplate
Los objetos incrustados de MongoDB no tienen ID(valor nulo) (4)
En el contexto de una arquitectura REST, tiene todo el sentido de que los documentos anidados tienen sus propios identificadores.
- La implementación de la persistencia debe ser independiente de la representación de recursos. Como consumidor de API, no me importa si está utilizando mongo o mysql. Si anida documentos sin id en mongo, intente imaginar cómo cambiar la capa de persistencia a una base de datos relacional. Ahora haga el mismo ejercicio pensando previamente con un enfoque de implementación independiente. Los modelos de documentos anidados en una base de datos relacional, documentos raíz y anidados serán entidades / tablas diferentes, cada una con sus propios identificadores. La raíz podría tener una relación de uno a muchos con el documento anidado.
- Es posible que necesite acceder a un documento anidado directamente en lugar de secuencialmente. Es posible que no necesite identificadores únicos absolutos, como los emitidos por mongo, pero todavía necesitaré algún identificador único local. Esto es, único dentro del documento raíz.
Después de haber argumentado mi punto sobre la necesidad de identificadores en documentos anidados @dcrosta ya ha dado una respuesta correcta sobre cómo rellenar el campo _id en mongo.
Espero que esto ayude.
Tengo una pregunta con respecto a MongoDB con Spring Data. Tengo estas clases de dominio:
@Document
public class Deal {
@Id
private ObjectId _id;
private Location location;
private User user;
private String description;
private String title;
private String price;
private boolean approved;
private Date expirationDate;
private Date publishedDate;
}
@Document
public class Location {
@Id
private ObjectId _id;
private Double latitude;
private Double longitude;
private String country;
private String street;
private String zip;
}
@Document
public class User {
@Id
private ObjectId _id;
private String email;
private String password;
private String profile_image_url;
private Collection<Deal> deals = new ArrayList<Deal>();
}
Con estos dominios puedo con éxito CRUD. Solo hay un problema. Al guardar un usuario con ofertas, las ofertas y la ubicación se ajustan a nid cuando se guardan en MongoDB. ¿Por qué no puede MongoDB generar identificaciones únicas para objetos incrustados?
El resultado después de guardar un usuario con una sola oferta:
{ "_id" : ObjectId( "4fed0591d17011868cf9c982" ),
"_class" : "User",
"email" : "[email protected]",
"password" : "mimi",
"deals" : [
{ "_id" : null,
"location" : { "_id" : null,
"latitude" : 2.22,
"longitude" : 3.23445,
"country" : "Denmark",
"street" : "Denmark road 77",
"zip" : "2933" },
"description" : "The new Nexus 7 Tablet. A 7 inch tablet from Google.",
"title" : "Nexus 7",
"price" : "1300",
"approved" : false,
"expirationDate" : Date( 1343512800000 ),
"publishedDate" : Date( 1340933521374 ) } ] }
Como puede ver en el resultado, la ID de oferta y ubicación se establece en NULL.
Las operaciones CRUD de MongoDB ( insert
, update
, find
, remove
) operan exclusivamente en documentos de nivel superior, aunque, por supuesto, puede filtrar por campos en documentos incrustados. Los documentos incrustados siempre se devuelven dentro del documento principal.
El campo _id
es un campo obligatorio del documento principal y, por lo general, no es necesario ni está presente en los documentos incrustados. Si necesita un identificador único, puede crearlos y puede usar el campo _id
para almacenarlos si es conveniente para su código o su modelo mental; más típicamente, se nombran después de lo que representan (por ejemplo, "username", "otherSystemKey", etc.). Ni MongoDB en sí, ni ninguno de los controladores _id
automáticamente un campo _id
, excepto en el documento de nivel superior.
Específicamente en Java, si desea generar valores de ObjectId para el campo _id
en documentos incrustados, puede hacerlo con:
someEmbeddedDoc._id = new ObjectId();
Mongo no crea ni necesita _id
s en documentos incrustados. Puede agregar un campo _id
si lo desea, lo he hecho.
@Document
public class Location {
@Id
private ObjectId _id;
public Location() {
this._id = ObjectId.get();
}
}
@Document
public class User {
@Id
private ObjectId _id;
public User() {
this._id = ObjectId.get();
}
}
Esto funciona muy bien para mí.
Un _id no está configurado en subdocumentos por defecto solo en documentos raíz.
Deberá definir un _id para sus subdocumentos al insertar y actualizar.