2017-01-15 24 views
5

Mam tablicę (jako wyniku zapytania MongoDB) z pewnymi elementami tak:Wybierz zagnieżdżonego obiektu Array i zastąpić go

{ 
    "_id": "ExxTDXJSwvRbLdtpg", 
    "content": [ 
     { 
      "content": "First paragraph", 
      "language":"en", 
      "timestamp":1483978498 
     }, 
     { 
      "content": "Erster Abschnitt", 
      "language":"de", 
      "timestamp":1483978498 
     } 
    ] 
} 

Ale muszę się tylko jedno pole zawartości dla każdego elementu tablicy dane , który powinien być wybrany przez język. Więc wynik powinien być (zakładając, wybierając angielskiej treści):

{ 
    "_id": "ExxTDXJSwvRbLdtpg", 
    "content": "First paragraph" 
} 

zamiast się wszystkie dane treści ...

Próbowałem to zrobić z find(c => c.language === 'en), ale nie wiem jak użyj tego dla wszystkich elementów tablicy danych. Być może możliwe jest również uzyskanie danych bezpośrednio w zapytaniu mongodb?

Odpowiedz

3

Można wykonać iterację tablicy i zamienić wartość w środku.

var array = [{ _id: "ExxTDXJSwvRbLdtpg", content: [{ content: "First paragraph", language: "en", timestamp: 1483978498 }, { content: "Erster Abschnitt", language: "de", timestamp: 1483978498 }] }]; 
 

 
array.forEach(a => a.content = a.content.find(c => c.language === 'en').content); 
 

 
console.log(array);

Wersja z czekiem na content

var array = [{ _id: "ExxTDXJSwvRbLdtpg", content: [{ content: "First paragraph", language: "en", timestamp: 1483978498 }, { content: "Erster Abschnitt", language: "de", timestamp: 1483978498 }] }, { _id: "no_content" }, { _id: "no_english_translation", content: [{ content: "Premier lot", language: "fr", timestamp: 1483978498 }, { content: "Erster Abschnitt", language: "de", timestamp: 1483978498 }] }]; 
 

 
array.forEach(function (a) { 
 
    var language; 
 
    if (Array.isArray(a.content)) { 
 
     language = a.content.find(c => c.language === 'en'); 
 
     if (language) { 
 
      a.content = language.content; 
 
     } else { 
 
      delete a.content; 
 
     } 
 
    } 
 
}); 
 

 
console.log(array);

+0

będzie to praca na dokumentach z brakującymi dziedzinie partnerskiej? Ponieważ nie każdy element ma pole treści. – user3142695

+0

co powinno się wtedy stać? –

+0

nie powinno być pola zawartości w wyniku ... – user3142695

3

Zważywszy, że _id i language są zmienne wejściowe, a następnie można użyć tego polecenia łączny aby uzyskać spodziewany Wynik:

db.collection.aggregate([{ 
    $match: { 
    _id: _id, 
    } 
}, { 
    $unwind: '$content' 
}, { 
    $match: { 
    'content.language': language, 
    } 
}, { 
    $project: { 
    _id: 1, 
    content: '$content.content' 
    } 
}]) 
+0

Używam meteoru i myślę, że agregacja nie będzie działać z tym :-( – user3142695

+0

oh, jestem też devem Meteora :) możesz użyć agregacji w serwer z tym pakietem [meteorhacks: aggregate] (https://github.com/meteorhacks/meteor-aggregate) – Khang

1
var aobjs = [{ 
    "_id": "ExxTDXJSwvRbLdtpg", 
    "content": [ 
    { 
     "content": "First paragraph", 
     "language":"en", 
     "timestamp":1483978498 
    }, 
    { 
     "content": "Erster Abschnitt", 
     "language":"de", 
     "timestamp":1483978498 
    } 
    ] 
}]; 

var result = aobjs.map(o => ({ id: o._id, content: o.content.find(c => c.language === 'en').content })); 

ta zwraca obiekt dla każdego z tylko id i treści. W tym przykładzie, wynik będzie:

[{id: 'ExxTDXJSwvRbLdtpg', treści: 'Pierwszy akapit'}]

0

Można spróbować regularne kwerendy coś jak poniżej.

Korzystanie elemMatch

db.collection.find({"_id": ObjectId("ExxTDXJSwvRbLdtpg")}, { "content": { $elemMatch: { "language": "en" } } }); 

lub

Korzystanie positional operatora

db.collection.find({"_id": ObjectId("ExxTDXJSwvRbLdtpg"), "content.language" : "en"}, { "content.$":1});