1
votes

Liste des valeurs de nom dans le dictionnaire à importer dans MongoDB

Je suis coincé dans un problème où je dois convertir une liste en Dictionary> BsonDocument pour l'importer dans MongoDB.

La liste a le nom de la colonne et les valeurs à insérer dans cette colonne. Mais je reçois déjà une exception de sortie de clé dès que le compilateur entre en boucle. Une suggestion?

void Main()
{
    List<ListRow> myList = new List<ListRow>();
    myList.Add(new ListRow { columnName = "column1", results = new List<string> { "a1", "b1", "c1" } });
    myList.Add(new ListRow { columnName = "column2", results = new List<string> { "a2", "b2", "c2" } });
    myList.Add(new ListRow { columnName = "column3", results = new List<string> { "a3", "b3", "c3" } });

    List<BsonDocument> batch = new List<BsonDocument>();
    foreach (var row in myList)
    {
        var dictionary = row.results.ToDictionary(x => row.columnName, x => x);
        batch.Add(dictionary);
    }
    // Print batch
    // Add to MongoDB
}

public class ListRow
{
    public string columnName { get; set; }
    public List<string> results { get; set; }
}

Résultat attendu pour l'extraction

entrez la description de l'image ici


6 commentaires

Quelle ligne lance l'erreur? est-ce var dictionary = row.results ...?


Oui, le row.results lance une erreur.


Donc, il semble que vos données aient des clés dupliquées. ToDictionary () lèvera une erreur dans ce cas. Vous pouvez utiliser .GroupBy (x => rowColumnName) et boucler la collection groupée


Et je viens de voir que vous répétez la même clé: row.results.ToDictionary (x => row.columnName, x => x); C'est normal que vous ayez cette erreur


Mon hypothèse est-elle correcte?


Pouvez-vous nous montrer le résultat attendu au format JSON?


3 Réponses :


1
votes

Vous essayez de créer une entrée dans l'itération. ToDictionary vise à créer tout le dictionnaire.

class Program
{
    static void Main(string[] args)
    {
        List<ListRow> myList = new List<ListRow>
        {
            new ListRow {columnName = "column1", results = new List<string> {"a1", "b1", "c1"}},
            new ListRow {columnName = "column2", results = new List<string> {"a2", "b2", "c2"}},
            new ListRow {columnName = "column3", results = new List<string> {"a3", "b3", "c3"}}
        };

        BsonDocument batch = myList.ToDictionary(x => x.columnName, x => x.results).ToBsonDocument();
        // Print batch
        // Add to MongoDB
    }
}

public class ListRow
{
    public string columnName { get; set; }
    public List<string> results { get; set; }
}


2 commentaires

Il convertit la liste complète en un seul document. Bien que je doive stocker chaque résultat de liste en tant que document séparé à extraire via api. Par exemple a1-a3 comme document1, b1-b3 comme document 2 etc. Voir le résultat attendu dans ma mise à jour.


Pouvez-vous nous montrer un exemple au format JSON. Ce que vous avez écrit "document séparé" pour moi, signifie que db.document1.find () aboutit à ["a1", "a2", "a3"] ?



0
votes

Le nom de votre clé: row.columN est répété lorsque la liste est aplatie en dictionnaire. Vous pouvez essayer de générer une clé unique pour chaque élément de la liste.

    List<BsonDocument> batch = new List<BsonDocument>();
    foreach (var row in myList)
    {
        var i = 0;
        var dictionary = row.results.ToDictionary(x => $"{row.columnName}_{++i}", x => x);
        batch.Add(dictionary);
    }


1 commentaires

columnName sont déjà uniques. Je pense que le problème principal était l'incompréhension du fonctionnement de ToDictionary . Mais oui. C'est aussi une solution viable, si le x => x est vraiment prévu.



0
votes

D'accord. Si je comprends bien le problème, vous voulez d'abord transposer la matrice de

class Program
{
    static void Main(string[] args)
    {
        List<ListRow> myList = new List<ListRow>
        {
            new ListRow {columnName = "column1", results = new List<string> {"a1", "b1", "c1"}},
            new ListRow {columnName = "column2", results = new List<string> {"a2", "b2", "c2"}},
            new ListRow {columnName = "column3", results = new List<string> {"a3", "b3", "c3"}}
        };

        var result = myList
            .SelectMany(listRow => listRow.results.Select((item, index) => new {item, index}))
            .GroupBy(i => i.index, i => i.item)
            .Select(g => g.Select((x, index) => new {Col = myList[index].columnName, Value = x})
                .ToDictionary(x => x.Col, x => x.Value))
            .ToList();

        BsonDocument batch = new Dictionary<string, List<Dictionary<string, string>>> {{"root", result}}
            .ToBsonDocument();
        // {{ "root" : [{ "column1" : "a1", "column2" : "a2", "column3" : "a3" }, { "column1" : "b1", "column2" : "b2", "column3" : "b3" }, { "column1" : "c1", "column2" : "c2", "column3" : "c3" }] }}
        // or just
        BsonArray batchPart = BsonArray.Create(result);
        // {[{ "column1" : "a1", "column2" : "a2", "column3" : "a3" }, { "column1" : "b1", "column2" : "b2", "column3" : "b3" }, { "column1" : "c1", "column2" : "c2", "column3" : "c3" }]}
        // Print batch
        // Add to MongoDB
    }
}

public class ListRow
{
    public string columnName { get; set; }
    public List<string> results { get; set; }
}

que de nommer les colonnes avec column1, column2, column3, etc. Pour le problème de transposition j'ai eu cette solution .

À partir de là, j'ai élaboré cette solution, où j'avais besoin d'un nœud racine, ce qui n'est pas clair comment devrait ressembler à la question>

"a1", "b1", "c1"
"a2", "b2", "c2"
"a3", "b3", "c3"


1 commentaires

Merci, c'est ce dont j'ai besoin.