es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo realizar el Marshal/Unmarshal de una clave/campo JSON y BSON común que pueda tener dos formatos diferentes en Go?

Actualmente tengo datos de mongo almacenados en dos formas (específicamente para la clave de contenido) en una colección. A continuación se muestra una muestra parcial de los datos:

Formato 1.

{
    "type": "text",
    "content": "foobar",
    "extraTextData": "hello text"
}

Formato 2

{
    "type": "group",
    "content": [
        {
            "type": "text",
            "content": "grouped-foobar"
        },
        {
            "type": "image",
            "url": "https://abc.jpg"
        }
    ],
    "extraGroupData": "hello group"
}

Mi intento de estructurar esto en golang es el siguiente.

type C struct {
    Type string `json:"type" bson:"type"`
    Content ???
    *TextC 
    *GroupC
}
type TextC struct {
    ExtraTextData string `json:"extraTextData" bson:"extraTextData"`
}
type GroupC struct {
    ExtraGroupData string `json:"extraGroupData" bson:"extraGroupData"`
}

Estoy teniendo problemas para configurar la estructura del campo “content” que funcione para ambos formatos, TextC y GroupC.

El contenido para GroupC puede ser un array de C como – Content []C
El contenido para TextC también puede ser de tipo string.

¿Alguien puede ayudar y dar un ejemplo de cómo abordar esta situación?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Una posible solución para abordar esta situación puede ser crear una interfaz que defina las propiedades comunes entre las estructuras TextC y GroupC, y usarla como tipo para el campo Content. Aquí hay un ejemplo:

    type ContentData interface {
        // Define any common properties and methods between TextC and GroupC here
    }
    
    type C struct {
        Type    string        `json:"type" bson:"type"`
        Content []ContentData
        *TextC
        *GroupC
    }
    
    type TextC struct {
        ExtraTextData string `json:"extraTextData" bson:"extraTextData"`
    }
    
    type GroupC struct {
        ExtraGroupData string `json:"extraGroupData" bson:"extraGroupData"`
    }
    
    // Define any additional properties and methods for TextC and GroupC here,
    // and make sure they implement the ContentData interface
    
    type TextData struct {
        Text string
    }
    
    type ImageData struct {
        Url string
    }
    
    // Implement the ContentData interface for TextData and ImageData
    func (t TextData) ContentData() {}
    func (i ImageData) ContentData() {}
    
    // Example usage:
    c1 := C{
        Type: "text",
        Content: []ContentData{
            TextData{Text: "foobar"},
        },
        TextC: &TextC{
            ExtraTextData: "hello text",
        },
    }
    
    c2 := C{
        Type: "group",
        Content: []ContentData{
            TextData{Text: "grouped-foobar"},
            ImageData{Url: "https://abc.jpg"},
        },
        GroupC: &GroupC{
            ExtraGroupData: "hello group",
        },
    }
    

    En este ejemplo, hemos definido una interfaz llamada ContentData que define las propiedades comunes y los métodos entre las estructuras TextC y GroupC. Luego hemos utilizado esta interfaz como tipo para el campo Content en la estructura C.

    Para que esto funcione, también hemos definido estructuras adicionales (TextData e ImageData) que implementan la interfaz ContentData, y hemos agregado propiedades y métodos adicionales para las estructuras TextC y GroupC.

    Al crear una nueva estructura C, podemos agregar cualquier número de objetos ContentData al campo Content, que pueden ser estructuras TextData o ImageData en este ejemplo.

    Este enfoque nos permite manejar ambos formatos de los datos de mongo de manera flexible y segura en términos de tipos, al tiempo que mantenemos el código legible y fácil de entender.

Comments are closed.