3 dias para llegar aqui… 😦
Introducción
Introducción al curso y prerequisitos del curso
¿Qué es GraphQL?
Conceptos básicos
Schema y types
Queries y Resolvers
Sirviendo el API en la web
Custom Types
Argumentos
Configuración de base de datos
Integrando una base de datos
Mutations e Inputs
Repaso - Creando el tipo Estudiante
Nested Types
Resolver de tipos
Errores
Conceptos avanzados
Alias y fragments
Variables
Enums
Interfaces - Tipo Monitor
Directivas
Unions
Consumiendo el API
Preparando API para producción
HTTP requests
Clientes de GraphQL
Consumiendo el API desde un frontend simple
Cierre del curso
Aún no tienes acceso a esta clase
Crea una cuenta y continúa viendo este curso
Unions permite agrupar varios custom types sin importar si tienen algo en común, su sintaxis es la siguiente:
union SearchResult = CustomType1 | CustomType2 | CustomType3
Al momento de realizar una query que retorna una union podemos identificar el tipo de dato solicitando el campo __typename
.
Aportes 20
Preguntas 2
3 dias para llegar aqui… 😦
Query para crear indices:
db.<collection>.createIndex({"$**": "text"})
Confieso que olvide colocar el () en to array y casi pierdo la cabeza. Pero por fin funcionó.Por cierto, el índice implementado es de tipo text, esto es, un índice que permite realizar búsquedas de texto en los datos que sean de tipo string en la base de datos. Hay muuuchos otros índices, los invito a leer mas sobre estos en: https://docs.mongodb.com/manual/indexes/
searchItems: async (root, { keyword }) => {
let db
let items
let malwares
let providers
try{
db = await connectDb()
malwares = await db.collection('Malwares').find({ $text: { $search: keyword }}).toArray()
providers = await db.collection('Companies').find({ $text: { $search: keyword }}).toArray()
items = [...malwares, ...providers]
console.log("items de consulta" + items)
} catch (error){
errorHandler(error)
}
return items
}
Para los que están usando Mongo Compass y no pueden crear los índices:
En las últimas versiones de Compass, hasta abajo en una franja aparece una sección “>_MongoSH”. incluso a mí al día de hoy me aparece en beta. (Si no les aparece actualicen a la última versión de Compass. Yo tengo la versión 1.22.1)
.
Den clic en ella y accederán al Shell de Mongo. Ahí pueden correr los siguientes comandos.
.
show dbs // Lista todas sus bases de datos.
use <nombre de su base de datos> // use graphql-api_db por ejemplo.
show collections // Lista las colecciones en esa base de datos.
db.courses.createIndex({"$**": "text"}) // Pueden cambiar el "courses" en caso de que sus colecciones tengan diferente nombre.
db.students.createIndex({"$**": "text"}) // Lo mismo para "students" en caso de nombre distinto.
Eso debería dejar listos los índices para poder trabajar con ellos y correr el query.
Les recomiendo esta clase si quieren que les quede más claro.
https://platzi.com/clases/1533-mongodb/18493-consultas-mas-rapidas-con-indices/
Unions permite hacer lo mismo que interfaces pero de una manera más extrema.
Agregamos una union a nuestro schema:
union GlobalSearch = Course | Student | Monitor
type Query {
"Devuelve todos los cursos"
getCourses: [Course]
"Devuelve un curso"
getCourse(id: ID!): Course
"Devuelve todos los estudiantes"
getPeople: [Person]
"Devuelve un estudiante"
getPerson(id: ID!): Person
"Ejecuta una búsqueda global"
searchItems(keyword: String!): [GlobalSearch]
}
Agregamos en types.js:
GlobalSearch: {
__resolveType: (item, context, info) => {
if (item.title){
return 'Course'
}
if (item.phone) {
return 'Monitor'
}
return 'Student'
}
}
Agregamos en queries.js:
searchItems: async (root, { keyword }) => {
let db
let items
let courses
let people
try {
db = await connectDb()
courses = await db.collection('courses').find({ $text: { $search: keyword } }).toArray()
people = await db.collection('students').find({ $text: { $search: keyword } }).toArray()
items = [...courses, ...people]
} catch (error) {
errorHandler(error);
}
return items
}
Antes de continuar, debemos crear índices en MongoDB:
db.courses.createIndex({ "$**": "text" })
& db.students.createIndex({ "$**": "text" })
Y ahora podemos hacer por ejemplo esta querie:
{
searchItems(keyword: "programming") {
__typename
... on Course {
title
description
topic
}
... on Monitor {
name
phone
}
... on Student {
name
email
}
}
}
Y como el keyword que (al menos yo escogí) es ‘programming’, regresa un resultado:
{
"data": {
"searchItems": [
{
"__typename": "Course",
"title": "New cool title",
"description": "My description",
"topic": "Programming"
},
{
"__typename": "Course",
"title": "My title 3",
"description": "My description 3",
"topic": "Programming"
}
]
}
}
Creacion de Indices
db.courses.createIndex({"$**": "text"})
db.students.createIndex({"$**": "text"})
Mas info de este tipo de indices : https://docs.mongodb.com/manual/core/index-text/
Si quieren ampliar un poco mas sobre el tema https://platzi.com/clases/1533-mongodb/18493-consultas-mas-rapidas-con-indices/
No entiendo muy bien el úso de los índices, alguien me puede explicar cómo funcionan?
Excelente.
{
searchItems(keyword: "ejemplo"){
__typename
... on Course{
title
description
}
... on Monitor {
name
phone
}
... on Student {
name
email
}
}
}
{
"data": {
"searchItems": [
{
"__typename": "Course",
"title": "Curso de ejemplo numero 1",
"description": "una descripcion 1"
}
]
}
}
No me quedo claro una cosa en la creación de indices. El indice se crea para todos los campos tipo String de la colección o para un solo campo ?
Hola, alguien sabe por qué me regresa este error?
{ MongoError: text index required for $text query
at MessageStream.messageHandler (/Users/andresnava/Documents/Programacion/graphQL/platzi-dir/node_modules/mongodb/lib/cmap/connection.js:261:20)
at emitOne (events.js:116:13)
at MessageStream.emit (events.js:211:7)
at processIncomingData (/Users/andresnava/Documents/Programacion/graphQL/platzi-dir/node_modules/mongodb/lib/cmap/message_stream.js:144:12)
at MessageStream._write (/Users/andresnava/Documents/Programacion/graphQL/platzi-dir/node_modules/mongodb/lib/cmap/message_stream.js:42:5)
at doWrite (_stream_writable.js:396:12)
at writeOrBuffer (_stream_writable.js:382:5)
at MessageStream.Writable.write (_stream_writable.js:290:11)
at TLSSocket.ondata (_stream_readable.js:639:20)
at emitOne (events.js:116:13)
operationTime: Timestamp { _bsontype: 'Timestamp', low_: 9, high_: 1582842781 },
ok: 0,
errmsg: 'text index required for $text query',
code: 27,
codeName: 'IndexNotFound',
'$clusterTime':
{ clusterTime: Timestamp { _bsontype: 'Timestamp', low_: 9, high_: 1582842781 },
signature: { hash: [Object], keyId: [Object] } },
name: 'MongoError',
[Symbol(mongoErrorContextSymbol)]: {} }
{ MongoError: text index required for $text query
at MessageStream.messageHandler (/Users/andresnava/Documents/Programacion/graphQL/platzi-dir/node_modules/mongodb/lib/cmap/connection.js:261:20)
at emitOne (events.js:116:13)
at MessageStream.emit (events.js:211:7)
at processIncomingData (/Users/andresnava/Documents/Programacion/graphQL/platzi-dir/node_modules/mongodb/lib/cmap/message_stream.js:144:12)
at MessageStream._write (/Users/andresnava/Documents/Programacion/graphQL/platzi-dir/node_modules/mongodb/lib/cmap/message_stream.js:42:
Programacion/graphQL/platzi-dir
▶ node index.js
Server is listening at http://localhost:3000/api
{ MongoError: text index required for $text query
at MessageStream.messageHandler (/Users/andresnava/Documents/Progr
amacion/graphQL/platzi-dir/node_modules/mongodb/lib/cmap/connection.js
:261:20)
at emitOne (events.js:116:13)
at MessageStream.emit (events.js:211:7)
at processIncomingData (/Users/andresnava/Documents/Programacion/g
raphQL/platzi-dir/node_modules/mongodb/lib/cmap/message_stream.js:144:
12)
at MessageStream._write (/Users/andresnava/Documents/Programacion/
graphQL/platzi-dir/node_modules/mongodb/lib/cmap/message_stream.js:42:
5)
at doWrite (_stream_writable.js:396:12)
at writeOrBuffer (_stream_writable.js:382:5)
at MessageStream.Writable.write (_stream_writable.js:290:11)
at TLSSocket.ondata (_stream_readable.js:639:20)
at emitOne (events.js:116:13)
operationTime: Timestamp { _bsontype: 'Timestamp', low_: 1, high_: 1
582842800 },
ok: 0,
errmsg: 'text index required for $text query',
code: 27,
codeName: 'IndexNotFound',
'$clusterTime':
{ clusterTime: Timestamp { _bsontype: 'Timestamp', low_: 2, high_: 1582842800 },
signature: { hash: [Object], keyId: [Object] } },
name: 'MongoError',
[Symbol(mongoErrorContextSymbol)]: {} }
{ MongoError: text index required for $text query
at MessageStream.messageHandler (/Users/andresnava/Documents/Programacion/graphQL/platzi-dir/node_modules/mongodb/lib/cmap/connection.js:261:20)
at emitOne (events.js:116:13)
at MessageStream.emit (events.js:211:7)
at processIncomingData (/Users/andresnava/Documents/Programacion/graphQL/platzi-dir/node_modules/mongodb/lib/cmap/message_stream.js:144:12)
at MessageStream._write (/Users/andresnava/Documents/Programacion/graphQL/platzi-dir/node_modules/mongodb/lib/cmap/message_stream.js:42:5)
at doWrite (_stream_writable.js:396:12)
at writeOrBuffer (_stream_writable.js:382:5)
at MessageStream.Writable.write (_stream_writable.js:290:11)
at TLSSocket.ondata (_stream_readable.js:639:20)
at emitOne (events.js:116:13)
operationTime: Timestamp { _bsontype: 'Timestamp', low_: 1, high_: 1582842800 },
ok: 0,
errmsg: 'text index required for $text query',
code: 27,
codeName: 'IndexNotFound',
'$clusterTime':
{ clusterTime: Timestamp { _bsontype: 'Timestamp', low_: 2, high_: 1582842800 },
signature: { hash: [Object], keyId: [Object] } },
name: 'MongoError',
[Symbol(mongoErrorContextSymbol)]: {} }
searchItems: async (root, { keyword }) => {
let db;
let items;
let courses;
let people;
try {
db = await connectDb();
courses = await db.collection('courses').find(
{ $text: { $search: keyword} }
).toArray();
people = await db.collection('students').find(
{ $text: { $search: keyword} }
).toArray();
items = [...courses, ...people];
} catch (error) {
errorHandler(error);
}
return items;
}
Alguno sabe cómo solucionar el tema de consultas que no sea obligatio el match de la palabra completa, me explico, si quiero buscar “carro”. a medida que escriba “ca” pueda ir consultando y me traiga esa info.
Gracias.
De esta manera podriamos buscar de manera mas dinamica, mediante busqueda regex, sin embargo hasta donde he encontrado si quiero que busque en todos los campos con una sola query find, no lo permite, debemos ingresar cada field
const courses = await db
.collection("courses")
.find({
title: {
$regex: `${keyword}.*`,
},
})
Alguien me puede ayudar o indicar como hacer la indexacion con mongodb compass ?
Excelente explicacion
Para los que usamos Ubuntu, los index los trate de crear por Atlas, pero no funcionaron en un principio. Los podemos crear por la linea de comando de mongo shell, con la misma instrucción tal como los explica el profe.
dejo aca como conectarse a tu cluster desde robomongo https://stackoverflow.com/questions/43694799/how-can-i-connect-to-mongodb-atlas-using-robomongo
Para los que están utilizando MongoDB Atlas, hay una forma nueva de crear y utilizar search indexes. Esta forma utliliza aggregate en vez de find. La documentación esta en: https://docs.atlas.mongodb.com/reference/atlas-search/path-construction#wildcard-field-search
{
"mappings": {
"dynamic": true
}
}
const courses = await db
.collection('courses')
.aggregate([
{
$search: {
index: 'default',
text: {
query: keyword,
path: { wildcard: '*' },
},
},
},
])
.toArray();
Asi logramos crear el query de esta lección usando MongoDB Atlas sin conectarnos desde el shell y creando el index del curso.
Les facilito aquí la documentación para que puedan profundizar un poco más en la clase.
¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.