mongoDB - mongoArray

 
Vista:
sin imagen de perfil
Val: 18
Ha mantenido su posición en mongoDB (en relación al último mes)
Gráfica de mongoDB

mongoArray

Publicado por Erwis (7 intervenciones) el 12/06/2017 20:03:58
Buenos días estoy empezando con mongoDb . (nota: la colecion , array y documento se asemeja al real solo que lo coloque de forma sencilla) tengo un problema vease primero el ejemplo de la collection que tengo:
1
2
3
db.usuario.insert({"id":"123","nombre":"erwis"
	seguridad:[{"pregunta":"'¿mascota favorita?","respuesta":"chichi",}]
});

yo necesito validar que un usuario no inserte mas de dos veces la misma pregunta. notese que la pregunta esta dentro de una array de seguridad porque un usuario puede tener varias preguntas asociadas.

haciendo el campo pregunta unique no sirve porque despues otro usuario puede tener la misma pregunta y no permite insertarlo.

haciendo los campos id y pregunta unique ejemplo: db.usuario.ensureIndex({"id":1,"pregunta":1},{unique:true})
tampoco sirve. no lo toma en cuenta.

probe tambien con $set, $addToSet , findAndModify . y nada igual se duplica.
no se si alguien sabe como validar esto. o sea necesito es que la pregunta no se repita para el mismo usuario.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de xve
Val: 38
Ha disminuido 1 puesto en mongoDB (en relación al último mes)
Gráfica de mongoDB

mongoArray

Publicado por xve (44 intervenciones) el 13/06/2017 07:35:53
Hola Erwis, con un indice no te funcionara, ya que que los indices son para todos los documentos, y tu quieres un indice para un array dentro del documento.

La única manera que se me ocurre, es que utilices un findAndModify, que únicamente lo añada si no existe.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 18
Ha mantenido su posición en mongoDB (en relación al último mes)
Gráfica de mongoDB

mongoArray

Publicado por Erwis (7 intervenciones) el 13/06/2017 13:58:00
Gracias por contestar. findAndModify igual deja pasar duplicado en el array de documento. lo que se me ocurre es poner algo asi como un if else dentro de el pero no se si esto sea posible de hacer si tienes un enlace donde se haga algo parecido seria bueno. una solución que encontré por Internet y la comparto con lo que lean este articulo es no hacer un array de documento si no crear documento dentro de documento voy a poner el ejemplo en este ejemplo si funciona el findAndModifi a la perfección:

1
2
3
db.usuario.insert({"id":"123","nombre":"erwis"
	seguridad:{"mascota favorita":{"chichi","color favorito":{"rojo"}}]
});

explico dentro de la colección de seguridad se crearan nuevas colecciones donde el nombre de la pregunta pasaría a ser nombre de la colección y obvio pueden insertar un documento con cualquier estructura.

ahora a mi me gustaría hacerlo en un array como lo tenia porque lo veo mejor con mejor lógica y mas ordenado creo. no se si sea posible ojala que si.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 40
Ha aumentado 1 puesto en mongoDB (en relación al último mes)
Gráfica de mongoDB

mongoArray

Publicado por Andrés (14 intervenciones) el 16/06/2017 15:45:32
Prueba con:

1
2
3
db.usuario.update( {nombre:'erwis'}, { $addToSet:{seguridad:[{pregunta:'¿mascota favorita?',respuesta:'chichi'}]} }, {upsert:true} );
 
MongoDB Enterprise > db.usuario.find().count();
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
MongoDB Enterprise > db.usuario.update( {nombre:'erwis'}, { $addToSet:{seguridad:{pregunta:'¿mascota favorita?',respuesta:'chichi'}} }, {upsert:true} );
WriteResult({
	"nMatched" : 0,
	"nUpserted" : 1,
	"nModified" : 0,
	"_id" : ObjectId("5943e3c87d04e213a80e2202")
})
MongoDB Enterprise > db.usuario.find().count();
1
MongoDB Enterprise > db.usuario.update( {nombre:'erwis'}, { $addToSet:{seguridad:{pregunta:'¿mascota favorita?',respuesta:'chichi'}} }, {upsert:true} );
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
MongoDB Enterprise > db.usuario.find().count();
1
MongoDB Enterprise > db.usuario.findOne();
{
	"_id" : ObjectId("5943e3c87d04e213a80e2202"),
	"nombre" : "erwis",
	"seguridad" : [
		{
			"pregunta" : "¿mascota favorita?",
			"respuesta" : "chichi"
		}
	]
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 18
Ha mantenido su posición en mongoDB (en relación al último mes)
Gráfica de mongoDB

mongoArray

Publicado por Erwis (7 intervenciones) el 16/06/2017 21:17:53
Buen día muchas gracias amigo andrés. tu solución funciono perfectamente aunque me di cuenta que por alguna razon gracias a tu respuesta me di cuenta que mi insert estaba incorrecto por así decirlo porque lo aplicaba y después aplicaba tu update y segia duplicándose. luego cambie mi insert por:

db.usuario.insert({nombre:'erwis', seguridad:[[{pregunta:'¿mascota favorita?',respuesta:'chichi'}]]});

agregando como ven los corchetes extras. y de esta forma si funciono tu update.

GRACIAS POR TU RESPUESTA.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 18
Ha mantenido su posición en mongoDB (en relación al último mes)
Gráfica de mongoDB

mongoArray

Publicado por Erwis (7 intervenciones) el 17/06/2017 00:16:31
disculpa gracias por contestar pero despues me puse a hacer pruebas e igual me inserta repetido porque en tu forma de hacerlo el valida el documento completo o sea que sea igual pero si alguien manda la pregunta igual pero con otra respuesta este se inserta o sea no se esta validando el campo pregunta como tal que es lo que yo deseo hacer que no se repita la pregunta.
en otras palablas si tu mandas:

db.usuario.update( {nombre:'erwis'},{ $addToSet:{seguridad:[{pregunta:'¿mascota favorita?',respuesta:'chichi'}]} }, {upsert:true} );
y luego
db.usuario.update( {nombre:'erwis'}, { $addToSet:{seguridad:[{pregunta:'¿mascota favorita?',respuesta:'pepis'}]} }, {upsert:true} );

veras que se va a insertar la pregunta '¿mascota favorita? dos veces al mismo usuario.
y no deberia el mismo usuario tener dos veces esta pregunta.

quedo atento a sus sugerencias si saben como hacer esto por favor le agradezco su colaboracion.

gracias por contestar de igual forma.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 40
Ha aumentado 1 puesto en mongoDB (en relación al último mes)
Gráfica de mongoDB

mongoArray

Publicado por Andrés (14 intervenciones) el 17/06/2017 03:32:38
Prueba ejecutando estos dos bloques como uno solo:

1
2
3
4
5
Primero:
db.usuario.update({nombre:'erwis','seguridad':{$elemMatch: {'pregunta':'¿mascota favorita?'}}},{$pull:{seguridad:{'pregunta':'¿mascota favorita?'}}},{upsert:false});
 
E inmediatamente, también puede ser push:
db.usuario.update({nombre:'erwis'},{$addToSet:{seguridad:{pregunta:'¿mascota favorita?',respuesta:'pepsi'}}},{upsert:true});



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
MongoDB Enterprise > db.usuario.update({nombre:'erwis','seguridad':{$elemMatch: {'pregunta':'¿mascota favorita?'}}},{$pull:{seguridad:{'pregunta':'¿mascota favorita?'}}},{upsert:false});
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
MongoDB Enterprise > db.usuario.update({nombre:'erwis'},{$addToSet:{seguridad:{pregunta:'¿mascota favorita?',respuesta:'pepsi'}}},{upsert:true});
WriteResult({
	"nMatched" : 0,
	"nUpserted" : 1,
	"nModified" : 0,
	"_id" : ObjectId("5944878d7d04e213a80e2550")
})
MongoDB Enterprise > db.usuario.find({nombre:'erwis','seguridad':{$elemMatch: {'pregunta':'¿mascota favorita?'}}});
{ "_id" : ObjectId("5944878d7d04e213a80e2550"), "nombre" : "erwis", "seguridad" : [ { "pregunta" : "¿mascota favorita?", "respuesta" : "pepsi" } ] }
MongoDB Enterprise > db.usuario.update({nombre:'tom','seguridad':{$elemMatch: {'pregunta':'¿mascota favorita?'}}},{$pull:{seguridad:{'pregunta':'¿mascota favorita?'}}},{upsert:false});
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
MongoDB Enterprise > db.usuario.update({nombre:'tom'},{$addToSet:{seguridad:{pregunta:'¿mascota favorita?',respuesta:'pepsi'}}},{upsert:true});
WriteResult({
	"nMatched" : 0,
	"nUpserted" : 1,
	"nModified" : 0,
	"_id" : ObjectId("5944878d7d04e213a80e2557")
})
MongoDB Enterprise > db.usuario.find({'seguridad':{$elemMatch: {'pregunta':'¿mascota favorita?'}}});
{ "_id" : ObjectId("5944878d7d04e213a80e2550"), "nombre" : "erwis", "seguridad" : [ { "pregunta" : "¿mascota favorita?", "respuesta" : "pepsi" } ] }
{ "_id" : ObjectId("5944878d7d04e213a80e2557"), "nombre" : "tom", "seguridad" : [ { "pregunta" : "¿mascota favorita?", "respuesta" : "pepsi" } ] }
MongoDB Enterprise > db.usuario.update({nombre:'erwis','seguridad':{$elemMatch: {'pregunta':'¿color favorito?'}}},{$pull:{seguridad:{'pregunta':'¿color favorito?'}}},{upsert:false});
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
MongoDB Enterprise > db.usuario.update({nombre:'erwis'},{$addToSet:{seguridad:{pregunta:'¿color favorito?',respuesta:'rojo'}}},{upsert:true});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
MongoDB Enterprise > db.usuario.find({nombre:'erwis','seguridad':{$elemMatch: {'pregunta':'¿color favorito?'}}});
{ "_id" : ObjectId("5944878d7d04e213a80e2550"), "nombre" : "erwis", "seguridad" : [ { "pregunta" : "¿mascota favorita?", "respuesta" : "pepsi" }, { "pregunta" : "¿color favorito?", "respuesta" : "rojo" } ] }
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
2
Comentar
sin imagen de perfil
Val: 18
Ha mantenido su posición en mongoDB (en relación al último mes)
Gráfica de mongoDB

mongoArray

Publicado por Erwis (7 intervenciones) el 17/06/2017 15:22:59
Gracias por estar pendiente amigo pero sigue sin función para mi. porque analizando y probando tu primera linea de comando borra el documento del array y la segunda lo inserta, en vez de solo modificar el elemento en cuestión. en este ejemplo que es real yo lo puse sencillo y hacer lo que dices es una opción viable pero igual no es correcta si te das cuenta de lo que te hable , ejemplo si guardara un campo con la fecha de registro cuando borre con tu primera linea se borraría dicha fecha.

ademas este es un ejemplo sencillo pero tengo otro donde hay un documento , dentro de este un array de documento y dentro de este array hay otro array de documento donde el ultimo de los array tendrá x cantidad de elementos. y no puede aplicar lo que tu dices porque es mucha información en juego.
la collecion principal seria animales
ejemplo {id,nombre,tipo:[{"npmbre":"aves","descripcion":"lalallala","fecha":new Date(),"partes":[{"nombre":"alas","fecha":new Date()}]}]}

si ves partes de un ave puede ser mucha información plumas pico alas patas etc si modifico el a array aves de tu forma se eliminaria las partes de esa ave y tendría que pasar el documento con toda la información de aves para que se inserte cosa que en la base de datos que deseo implementar es algo delicado borrar esta ultima información. por ello que lo mejor seria solo preguntar si cuando se agrega el elemento existe si no existe si agrégalo, si existe no hagas nada o modifica.

POR OTRO LADO EL PROBLEMA NO ES TANTO MODIFICAR EL ELEMENTO DEL ARREGLO DE ECHO ESO LO PUDE HACER ESPECIFICANDO EL CAMPO Y LA POSICIONES DEL ARREGLO, PERO AL MOMENTO DE INSERTAR UN DOCUMENTO NUEVO EN EL ARREGLO ESTE SE INSERTA AUNQUE ESTE HAY PORQUE NO CONSIGO LA MANERA DE VALIDAR QUE EJEMPLO EL CAMPO PREGUNTA SEA ÚNICO. SI USO UN INDICE EN EL ARREGLO LO VALIDA PERO ESTA EL INCONVENIENTE QUE NINGÚN OTRO USUARIO PUEDE USAR ESA MISMA PREGUNTA, YO CREO QUE LA SOLUCIÓN ES PROGRAMAR EN MONGO . PERO NO HE VISTO NINGUNA REFERENCIA DE COMO HACER LO QUE SE CONOCE EN BASE DE DATOS RELACIONALES COMO PLSQL.

AHORA IGUAL ESTO SE PIENSA VALIDAR DESDE EL BACKEND POR SI SE HACEN LA PREGUNTA Y DESDE EL MISMO FRONT PERO ME FUESE GUSTADO PODER HACERLO DESDE LA MISMA BASE DE DATOS MONGODB.

SI CONOCES UNA SOLUCIÓN A ESTO QUEDO ATENTO IGUAL GRACIAS POR TU PARTICIPACIÓN HE APRENDIDO NUEVAS COSAS GRACIAS A TUS CONTESTACIONES. .. CUALQUIER COSA HAY APARECE MI CORREO POR SI NECESITAS UNA MANO EN ALGO A LO MEJOR YO SE Y TE PUEDO CONTESTAR.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 40
Ha aumentado 1 puesto en mongoDB (en relación al último mes)
Gráfica de mongoDB

mongoArray

Publicado por Andrés (14 intervenciones) el 17/06/2017 16:56:43
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
db.system.js.save(
{
     _id: "customInsertFunction",
     value : function(document)
	{
 
		var usuario = db.usuario.findOne({nombre:document.nombre});
 
		if(usuario) {
			var seguridad = usuario.seguridad;
			for(var i=0;i<seguridad.length;i++) {
				if(seguridad[i].pregunta==document.seguridad[0].pregunta) {
					usuario.seguridad[i] = document.seguridad[0];
					db.usuario.save(usuario);
					return;
				}
			}
 
			usuario.seguridad.push(document.seguridad[0]);
			db.usuario.save(usuario);
			return;
 
		}else {
			db.usuario.insert(document);
			return;
		}
 
	}
}
);
 
db.loadServerScripts();
 
customInsertFunction({nombre:'erwis',seguridad:[{pregunta:'¿color favorito?', respuesta:'negro'}]});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
MongoDB Enterprise > customInsertFunction({nombre:'erwis',seguridad:[{pregunta:'¿color favorito?', respuesta:'negro'}]});
MongoDB Enterprise > db.usuario.find({});
{ "_id" : ObjectId("5945440442f0a567869a4f8c"), "nombre" : "erwis", "seguridad" : [ { "pregunta" : "¿color favorito?", "respuesta" : "negro" } ] }
MongoDB Enterprise > customInsertFunction({nombre:'erwis',seguridad:[{pregunta:'¿color favorito?', respuesta:'negro'}]});
MongoDB Enterprise > db.usuario.find({});
{ "_id" : ObjectId("5945440442f0a567869a4f8c"), "nombre" : "erwis", "seguridad" : [ { "pregunta" : "¿color favorito?", "respuesta" : "negro" } ] }
MongoDB Enterprise > customInsertFunction({nombre:'erwis',seguridad:[{pregunta:'¿color favorito?', respuesta:'rojo'}]});
MongoDB Enterprise > db.usuario.find({});
{ "_id" : ObjectId("5945440442f0a567869a4f8c"), "nombre" : "erwis", "seguridad" : [ { "pregunta" : "¿color favorito?", "respuesta" : "rojo" } ] }
MongoDB Enterprise > customInsertFunction({nombre:'erwis',seguridad:[{pregunta:'¿mascota favorita?', respuesta:'lobo'}]});
MongoDB Enterprise > db.usuario.find({});
{ "_id" : ObjectId("5945440442f0a567869a4f8c"), "nombre" : "erwis", "seguridad" : [ { "pregunta" : "¿color favorito?", "respuesta" : "rojo" }, { "pregunta" : "¿mascota favorita?", "respuesta" : "lobo" } ] }
MongoDB Enterprise > customInsertFunction({nombre:'erwis',seguridad:[{pregunta:'¿mascota favorita?', respuesta:'chichi'}]});
MongoDB Enterprise > db.usuario.find({});
{ "_id" : ObjectId("5945440442f0a567869a4f8c"), "nombre" : "erwis", "seguridad" : [ { "pregunta" : "¿color favorito?", "respuesta" : "rojo" }, { "pregunta" : "¿mascota favorita?", "respuesta" : "chichi" } ] }
MongoDB Enterprise > customInsertFunction({nombre:'erwis',seguridad:[{pregunta:'¿color favorito?', respuesta:'blanco'}]});
MongoDB Enterprise > db.usuario.find({});
{ "_id" : ObjectId("5945440442f0a567869a4f8c"), "nombre" : "erwis", "seguridad" : [ { "pregunta" : "¿color favorito?", "respuesta" : "blanco" }, { "pregunta" : "¿mascota favorita?", "respuesta" : "chichi" } ] }
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
2
Comentar
sin imagen de perfil
Val: 18
Ha mantenido su posición en mongoDB (en relación al último mes)
Gráfica de mongoDB

mongoArray

Publicado por Erwis (7 intervenciones) el 17/06/2017 18:28:48
Gracias por la ayuda prestada. esta solución funciono es lo que yo buscaba.

una vez mas gracias y que pases un buen dia.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 18
Ha mantenido su posición en mongoDB (en relación al último mes)
Gráfica de mongoDB

mongoArray

Publicado por Erwis (7 intervenciones) el 17/06/2017 18:29:59
Gracias esta solución si funciono es lo que andaba buscando.
Gracias por la paciencia y la colaboración prestada. feliz dia
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar