Mảng tra cứu Mongodb của các đối tượng

Là một phần của nhiệm vụ liên tục nhằm tăng tốc ứng dụng mà tôi đang làm việc, tôi nhận thấy mình được giao nhiệm vụ viết một quy trình tổng hợp MongoDB khá phức tạp. Tôi không tìm thấy tài liệu hiện có nào về cách hoàn thành nhiệm vụ hiện tại, vì vậy tôi nghĩ rằng mình nên chuyển tiếp và ghi lại giải pháp của mình cho các thế hệ tương lai

Tiện ích và biểu tượng

Hãy tưởng tượng chúng ta có hai bộ sưu tập MongoDB. Bộ sưu tập đầu tiên của chúng tôi chứa thông tin về


db.getCollection('icons').insert({
    _id: 2,
    name: 'Icon',
    uri: 'https://...'
});
6 trong hệ thống của chúng tôi


db.getCollection('widgets').insert({
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text'
        }
    ]
});

Mỗi widget có một


db.getCollection('icons').insert({
    _id: 2,
    name: 'Icon',
    uri: 'https://...'
});
7 và một danh sách gồm một hoặc nhiều đối tượng

db.getCollection('icons').insert({
    _id: 2,
    name: 'Icon',
    uri: 'https://...'
});
8. Mỗi đối tượng

db.getCollection('icons').insert({
    _id: 2,
    name: 'Icon',
    uri: 'https://...'
});
8 có một trường

{
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text',
            icon: {
                _id: 2,
                name: 'Icon',
                uri: 'https://...'
            }
        }
    ]
}
0 và một biểu tượng liên quan được tham chiếu bởi một

{
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text',
            icon: {
                _id: 2,
                name: 'Icon',
                uri: 'https://...'
            }
        }
    ]
}
1

Bộ sưu tập


{
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text',
            icon: {
                _id: 2,
                name: 'Icon',
                uri: 'https://...'
            }
        }
    ]
}
2 của chúng tôi chứa một số thông tin cơ bản về từng biểu tượng


db.getCollection('icons').insert({
    _id: 2,
    name: 'Icon',
    uri: 'https://...'
});

Mục tiêu là viết một tập hợp trả về các vật dụng của chúng tôi với các tài liệu biểu tượng được liên kết được đính kèm với từng đối tượng


db.getCollection('icons').insert({
    _id: 2,
    name: 'Icon',
    uri: 'https://...'
});
8 tương ứng


{
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text',
            icon: {
                _id: 2,
                name: 'Icon',
                uri: 'https://...'
            }
        }
    ]
}

Làm việc thông qua đường ống

Tập hợp hoàn thành mục tiêu này hoạt động trong sáu giai đoạn. Hãy làm việc qua từng giai đoạn một. Chúng tôi sẽ bắt đầu bằng cách


{
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text',
            icon: {
                _id: 2,
                name: 'Icon',
                uri: 'https://...'
            }
        }
    ]
}
4ing mảng

db.getCollection('icons').insert({
    _id: 2,
    name: 'Icon',
    uri: 'https://...'
});
8 của chúng tôi


db.getCollection('widgets').insert({
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text'
        }
    ]
});
3

Điều này tạo ra một tài liệu mới cho mỗi cặp widget/thông tin


db.getCollection('widgets').insert({
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text'
        }
    ]
});
4

Tiếp theo, chúng tôi sẽ


{
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text',
            icon: {
                _id: 2,
                name: 'Icon',
                uri: 'https://...'
            }
        }
    ]
}
6 biểu tượng được liên kết với

{
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text',
            icon: {
                _id: 2,
                name: 'Icon',
                uri: 'https://...'
            }
        }
    ]
}
1 đã cho


db.getCollection('widgets').insert({
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text'
        }
    ]
});
7

Tài liệu kết quả của chúng tôi bây giờ sẽ có một danh sách các biểu tượng trong trường


{
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text',
            icon: {
                _id: 2,
                name: 'Icon',
                uri: 'https://...'
            }
        }
    ]
}
8


db.getCollection('widgets').insert({
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text'
        }
    ]
});
9

Đây là một bước đi đúng hướng, nhưng chúng tôi biết rằng mối quan hệ giữa


db.getCollection('icons').insert({
    _id: 2,
    name: 'Icon',
    uri: 'https://...'
});
8 và

{
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text',
            icon: {
                _id: 2,
                name: 'Icon',
                uri: 'https://...'
            }
        }
    ]
}
2 sẽ luôn là mối quan hệ một đối một. Chúng tôi sẽ luôn nhận được chính xác một biểu tượng là kết quả của

{
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text',
            icon: {
                _id: 2,
                name: 'Icon',
                uri: 'https://...'
            }
        }
    ]
}
6

Được trang bị kiến ​​thức này, chúng tôi biết rằng chúng tôi có thể


{
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text',
            icon: {
                _id: 2,
                name: 'Icon',
                uri: 'https://...'
            }
        }
    ]
}
4 trên

{
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text',
            icon: {
                _id: 2,
                name: 'Icon',
                uri: 'https://...'
            }
        }
    ]
}
8 và biến mảng

{
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text',
            icon: {
                _id: 2,
                name: 'Icon',
                uri: 'https://...'
            }
        }
    ]
}
8 của chúng tôi thành một đối tượng một cách an toàn


db.getCollection('icons').insert({
    _id: 2,
    name: 'Icon',
    uri: 'https://...'
});
6

db.getCollection('icons').insert({
    _id: 2,
    name: 'Icon',
    uri: 'https://...'
});
7

Nhưng bây giờ chúng ta cần sao lưu


db.getCollection('icons').insert({
    _id: 2,
    name: 'Icon',
    uri: 'https://...'
});
8 của mình thành một mảng. Chúng tôi có thể thực hiện điều này bằng cách

db.getCollection('widgets').insert({
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text'
        }
    ]
});
36 kết hợp các vật dụng của chúng tôi dựa trên

db.getCollection('widgets').insert({
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text'
        }
    ]
});
37 của chúng. Tuy nhiên chúng ta cần lưu ý giữ nguyên văn bản gốc tránh làm hỏng toàn bộ widget


db.getCollection('icons').insert({
    _id: 2,
    name: 'Icon',
    uri: 'https://...'
});
1

Tài liệu kết quả của chúng tôi chứa mảng


db.getCollection('icons').insert({
    _id: 2,
    name: 'Icon',
    uri: 'https://...'
});
8 của chúng tôi và tài liệu widget gốc, trước

db.getCollection('widgets').insert({
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text'
        }
    ]
});
36 trong trường

db.getCollection('widgets').insert({
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text'
        }
    ]
});
40


db.getCollection('icons').insert({
    _id: 2,
    name: 'Icon',
    uri: 'https://...'
});
0

Bước tiếp theo trong quy trình của chúng tôi là thay thế tài liệu gốc của chúng tôi bằng đối tượng


db.getCollection('widgets').insert({
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text'
        }
    ]
});
40 được hợp nhất với tài liệu gốc thực tế. Điều này sẽ ghi đè đối tượng

db.getCollection('icons').insert({
    _id: 2,
    name: 'Icon',
    uri: 'https://...'
});
8 trong

db.getCollection('widgets').insert({
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text'
        }
    ]
});
40 bằng mảng

db.getCollection('icons').insert({
    _id: 2,
    name: 'Icon',
    uri: 'https://...'
});
8 mới được nhóm lại với nhau của chúng ta


db.getCollection('icons').insert({
    _id: 2,
    name: 'Icon',
    uri: 'https://...'
});
1

Chúng tôi đang tiến gần đến mục tiêu của mình


db.getCollection('icons').insert({
    _id: 2,
    name: 'Icon',
    uri: 'https://...'
});
2

Một tác dụng phụ đáng tiếc của sự hợp nhất này là tài liệu kết quả của chúng tôi vẫn có một đối tượng


db.getCollection('widgets').insert({
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text'
        }
    ]
});
40 chứa đầy dữ liệu thừa. Là phần cuối cùng của việc dọn dẹp nhà cửa, hãy xóa trường đó


db.getCollection('icons').insert({
    _id: 2,
    name: 'Icon',
    uri: 'https://...'
});
3

Và với điều đó, chúng tôi còn lại với mục tiêu ban đầu của mình


{
    _id: 1,
    name: 'Name',
    info: [
        {
            iconId: 2,
            text: 'Text',
            icon: {
                _id: 2,
                name: 'Icon',
                uri: 'https://...'
            }
        }
    ]
}

Thành công

Tất cả cùng nhau

Đối với hậu thế, đây là toàn bộ đường dẫn tổng hợp


db.getCollection('icons').insert({
    _id: 2,
    name: 'Icon',
    uri: 'https://...'
});
5

Tôi sẽ là người đầu tiên nói rằng tôi không phải là chuyên gia về MongoDB và tôi thậm chí còn ít hiểu biết hơn về việc xây dựng các đường dẫn tổng hợp. Có thể có những cách khác, tốt hơn để hoàn thành cùng nhiệm vụ này. Nếu bạn biết về một quy trình tốt hơn, hiệu quả hơn mang lại kết quả tương tự, vui lòng cho tôi biết