Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Unions

20/25
Recursos

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

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

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

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/

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.

😃

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

  1. En MongoDB Atlas ir al cluster
  2. Entrar a la colleccion en la que se va a crear el index
  3. Ir al tab de search indexes
  4. Click en CREATE INDEX el default es el wildcard field search pero hay muchas opciones en los DOCS
    Default:
{
  "mappings": {
    "dynamic": true
  }
}
  1. Click en Create Index dentro de este menu.
  2. Utilizar el query para el text search usando aggergate con el nombre del index en el field index.
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.