sql >> Databasteknik >  >> NoSQL >> MongoDB

Fråga lokaliserad data i MongoDB

För att skapa en generisk fråga skulle man behöva aggregeringsramverket eftersom det har några praktiska operatörer som hjälper dig med detta. Till att börja med skulle du behöva konvertera det inbäddade dokumentet till array av nyckel/värdepar och sedan filtrera arrayen på nyckelfältet som passerar in i språket som parameter.

Konvertera till exempel dokumentet

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

till en array

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

med $objectToArray operatör. Du kan sedan filtrera denna array i nyckelfältet med $filter operatör som

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

där variabeln locale härleds från den passerade parametern.

När du har den filtrerade arrayen kräver att du skaffa värdefältet $arrayElemAt operatorn tillämpas på värdenyckeln som

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

Så i slutändan måste du köra en pipeline så här:

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]
        }
    } }
]);

Och med lite refaktorering:

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')
    } }
]);


  1. Hur ställer jag in lösenordet för Redis?

  2. MongoDB bästa praxis för referenser

  3. Kan rails scopes filtrera på antalet associerade klasser för ett givet fält

  4. MongoDB $indexOfBytes