MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Interrogazione di dati localizzati in MongoDB

Per creare una query generica sarebbe necessario il framework di aggregazione in quanto ha alcuni utili operatori per aiutarti in questo. Per cominciare, dovresti convertire il documento incorporato in un array di coppie chiave/valore e quindi filtrare l'array sul campo chiave passando nelle impostazioni locali come parametro.

Ad esempio, converti il ​​documento

  "title": {
    "en": "title en2",
    "de": "title de2"
  },

in un array

  "title": [
    { "k": "en", '"v": "title en2" },
    { "k": "de", "v": "title de2" }
  ],

utilizzando $objectToArray operatore. È quindi possibile filtrare questo array nel campo chiave utilizzando $filter operatore come

{
    '$filter': {
        'input': { '$objectToArray': '$title' },
        'cond': { '$eq': ['$$this.k', locale] }
    }
}

dove la locale variabile è derivata dal parametro passato.

Una volta che hai l'array filtrato, per ottenere il campo del valore è necessario $arrayElemAt operatore applicato sulla chiave del valore come

{ 
    '$arrayElemAt': ['$title.v', 0]
}

Quindi alla fine dovrai eseguire una pipeline come questa:

var locale = 'en';

db.cs.aggregate([
    { '$match': { "cID" : "00001" } },
    { '$addFields': {
        'title': {
            '$filter': {
                'input': { '$objectToArray': '$title' },
                'cond': { '$eq': ['$$this.k', locale] }
            }
        },
        'desc': {
            '$filter': {
                'input': { '$objectToArray': '$desc' },
                'cond': { '$eq': ['$$this.k', locale] }
            }
        }
    } },

    { '$addFields': {
        'title': { 
            '$arrayElemAt': ['$title.v', 0]
        },
        'desc': { 
            '$arrayElemAt': ['$desc.v', 0]
        }
    } }
]);

E con qualche refactoring:

var locale = 'en';
var getFilterOperatorExpression = function (field) {
    return {
        '$filter': {
            'input': { '$objectToArray': '$'+ field },
            'cond': { '$eq': ['$$this.k', locale] }
        }
    }
};
var getValueOperatorExpression = function (field) { 
    return { 
        '$arrayElemAt': ['$'+ field +'.v', 0]
    }
};

db.cs.aggregate([
    { '$match': { "cID" : "00001" } },
    { '$addFields': {
        'title': getFilterOperatorExpression('title'),
        'desc': getFilterOperatorExpression('desc'),
    } },

    { '$addFields': {
        'title': getValueOperatorExpression('title'),
        'desc': getValueOperatorExpression('desc')
    } }
]);