2017-01-15 35 views
5

Tôi có một mảng (như kết quả của một truy vấn MongoDB) với một số yếu tố như thế này:Chọn đối tượng mảng lồng nhau và thay thế nó

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

Nhưng tôi cần phải nhận được chỉ là một lĩnh vực nội dung duy nhất cho mỗi phần tử mảng dữ liệu , được chọn bởi ngôn ngữ. Vì vậy, kết quả nên được (giả sử chọn nội dung tiếng Anh):

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

thay vì nhận được tất cả các dữ liệu nội dung ...

Tôi cố gắng để làm điều đó với find(c => c.language === 'en), nhưng tôi không biết làm thế nào để sử dụng điều này cho tất cả các phần tử của mảng dữ liệu. Có lẽ nó cũng có thể nhận được dữ liệu trực tiếp như một truy vấn mongodb ??

Trả lời

3

Bạn có thể lặp lại mảng và thay thế giá trị bên trong.

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

Version với séc 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

Sẽ làm việc này cho các tài liệu với lĩnh vực nội dung còn thiếu? Bởi vì không phải mọi phần tử đều có một trường nội dung. – user3142695

+0

điều gì sẽ xảy ra sau đó? –

+0

không nên có trường nội dung trong kết quả ... – user3142695

3

Cho rằng _idlanguage là các biến đầu vào, sau đó bạn có thể sử dụng lệnh tổng hợp này để có được những kỳ vọng Kết quả:

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

Tôi đang sử dụng thiên thạch và tôi nghĩ rằng tổng hợp sẽ không hoạt động với điều đó :-( – user3142695

+0

oh, tôi là một nhà phát triển Meteor :) bạn có thể sử dụng tập hợp trong máy chủ với gói này [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 })); 

này trả về một đối tượng cho mỗi chỉ với id và nội dung. Trong ví dụ này, kết quả sẽ là:

[{id: 'ExxTDXJSwvRbLdtpg', nội dung: 'đoạn đầu tiên'}]

0

Bạn có thể thử truy vấn thường xuyên với một cái gì đó như dưới đây.

Sử dụng elemMatch

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

hoặc

Sử dụng positional hành

db.collection.find({"_id": ObjectId("ExxTDXJSwvRbLdtpg"), "content.language" : "en"}, { "content.$":1}); 
Các vấn đề liên quan