MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Cải thiện cấu trúc tổng hợp MongoDB

MongoDB gần đây đã giới thiệu cấu trúc tổng hợp mới của mình. Cấu trúc này cung cấp một giải pháp đơn giản hơn để tính toán các giá trị tổng hợp thay vì dựa vào các cấu trúc mạnh mẽ với một bản đồ được thu gọn.

Chỉ với một số nguyên thủy đơn giản, nó cho phép bạn tính toán, nhóm, định hình và thiết kế các tài liệu được chứa trong một bộ sưu tập MongoDB cụ thể. Phần còn lại của bài viết này mô tả việc tái cấu trúc thuật toán thu nhỏ bản đồ để sử dụng tối ưu nền tảng tổng hợp MongoDB mới. Mã nguồn hoàn chỉnh có thể được tìm thấy trong kho lưu trữ Datablend GitHub công khai.

1. Cấu trúc tổng hợp MongoDB

Nền tảng tổng hợp MongoDB dựa trên khái niệm Đường ống Linux nổi tiếng trong đó đầu ra của một lệnh được truyền qua băng tải hoặc được chuyển hướng để được sử dụng làm đầu vào cho lệnh tiếp theo . Trong trường hợp MongoDB, một số người vận hành được kết hợp thành một băng tải duy nhất chịu trách nhiệm xử lý luồng tài liệu.

Một số toán tử như $ match, $ limit và $ bỏ qua việc chấp nhận tài liệu làm đầu vào và đầu ra cùng một tài liệu nếu đáp ứng một số tiêu chí nhất định. Các toán tử khác, chẳng hạn như $ project và $ unwind, chấp nhận một tài liệu duy nhất làm dữ liệu đầu vào và thay đổi định dạng của nó hoặc tạo thành một số tài liệu dựa trên một phép chiếu nhất định.

Toán tử $ group cuối cùng chấp nhận một số tài liệu làm dữ liệu đầu vào và nhóm chúng thành một tài liệu bằng cách kết hợp các giá trị tương ứng. Biểu thức có thể được sử dụng trong một số toán tử này để tính toán các giá trị mới hoặc thực hiện các phép toán chuỗi.

Một số toán tử được kết hợp thành một đường dẫn duy nhất, áp dụng cho danh sách tài liệu. Bản thân băng tải được thực thi dưới dạng Lệnh MongoDB, dẫn đến một tài liệu MongoDB duy nhất, chứa một mảng tất cả các tài liệu xuất hiện ở cuối băng tải. Đoạn tiếp theo mô tả chi tiết thuật toán tái cấu trúc của sự tương đồng phân tử như một băng chuyền của những người vận hành. Hãy nhớ đọc (lại) hai bài viết trước để hiểu đầy đủ logic triển khai.

2. Đường ống của sự giống nhau về phân tử

Khi áp dụng băng tải cho một bộ sưu tập cụ thể, tất cả tài liệu có trong bộ sưu tập đó sẽ được chuyển làm đầu vào cho người vận hành đầu tiên. Bạn nên lọc danh sách này càng nhanh càng tốt để hạn chế số lượng tài liệu được chuyển qua đường ống. Trong trường hợp của chúng tôi, điều này có nghĩa là lọc toàn bộ tài liệu sẽ không bao giờ đáp ứng được yếu tố Tanimoto mục tiêu.

Do đó, bước đầu tiên, chúng tôi so sánh tất cả các tài liệu mà số lượng dấu vân tay nằm trong một ngưỡng nhất định. Nếu chúng tôi nhắm mục tiêu hệ số Tanimoto là 0,8 với kết nối đích chứa 40 dấu vân tay duy nhất, toán tử đối sánh $ sẽ trông như thế này:

{"$match" :
{ "fingerprint_count" : {"$gte" : 32, "$lte" : 50}}.
}

Chỉ các kết nối có số lượng vân tay từ 32 đến 50 mới được chuyển cho nhà điều hành đường ống tiếp theo. Để thực hiện quá trình lọc này, toán tử $ match có thể sử dụng chỉ mục mà chúng tôi đã xác định cho thuộc tính tệp_tính_tính_cấp. Để tính toán hệ số Tanimoto, chúng ta cần tính số lượng dấu vân tay phổ biến giữa một kết nối đầu vào nhất định và kết nối mục tiêu mà chúng ta đang nhắm mục tiêu.

Để làm việc ở cấp độ vân tay, chúng tôi sử dụng toán tử $ unwind. $ unwind xóa từng phần tử của mảng, trả về luồng tài liệu trong đó mảng được chỉ định được thay thế bằng một trong các phần tử của nó. Trong trường hợp của chúng tôi, chúng tôi áp dụng $ unwind cho dấu vân tay. Do đó, mỗi tài liệu tổng hợp sẽ tạo ra n tài liệu tổng hợp, trong đó n là số lượng dấu vân tay duy nhất có trong một tài liệu tổng hợp.

{"$unwind" :"$fingerprints"}

Để tính số lượng dấu vân tay phổ biến, chúng tôi sẽ bắt đầu bằng cách lọc tất cả tài liệu không có dấu vân tay nằm trong danh sách dấu vân tay của kết nối đích. Để thực hiện việc này, chúng tôi sử dụng lại toán tử $ match, lần này lọc thuộc tính vân tay, trong đó chỉ những tài liệu có chứa vân tay trong danh sách vân tay đích mới được hỗ trợ.

{"$match" :
{ "fingerprints" :
{"$in" : [ 1960 , 15111 , 5186 , 5371 , 756 , 1015 , 1018 , 338 , 325 , 776 , 3900 , ..., 2473] }
}
}

Vì chúng tôi chỉ đối sánh các vân tay có trong danh sách vân tay mục tiêu nên kết quả đầu ra có thể được sử dụng để tính tổng số vân tay phổ biến.

Để thực hiện việc này, chúng tôi áp dụng toán tử $ group cho kết nối tổng hợp, mặc dù chúng tôi tạo một loại tài liệu mới chứa số lượng dấu vân tay phù hợp (bằng cách cộng số lần xuất hiện), tổng số dấu vân tay kết nối đầu vào và biểu tượng mặt cười.

{"$group" :
{ "_id" : "$compound_cid". ,
"fingerprintmatches" : {"$sum" : 1} ,
"totalcount" : { "$first" : "$fingerprint_count"} ,
"smiles" : {"$first" : "$smiles"}
}
}

Bây giờ chúng ta có tất cả các tham số để tính toán hệ số Tanimoto. Để thực hiện việc này, chúng tôi sẽ sử dụng toán tử $ project, ngoài việc sao chép thuộc tính tổng hợp id và smile, còn thêm một thuộc tính mới được tính toán có tên là Tanimoto.

{
"$project"
:

{
"_id"
:
1
,

"tanimoto"
:
{
"$divide"
:
[
"$fingerprintmatches."
,
{
"$subtract"
:
[
{
"$add"
:
[
40
,
"$totalcount"
]
}
,
"$fingerprintmatches."
]
}
]
}
,

"smiles"
:
1

}

}

Vì chúng tôi chỉ quan tâm đến các kết nối có hệ số mục tiêu Tanimoto là 0,8, nên chúng tôi sử dụng toán tử đối sánh $ tùy chọn để lọc ra tất cả những kết nối không đạt đến hệ số này.

{"$match" :
{ "tanimoto" : { "$gte" : 0.8}
}

Bạn có thể tìm thấy lệnh của đường dẫn hoàn chỉnh bên dưới.

{"aggregate" : "compounds"} ,
"pipeline" : [
{"$match" :
{ "fingerprint_count" : {"$gte" : 32, "$lte" : 50} }
},
{"$unwind" : "$fingerprints"},
{"$match" :
{ "fingerprints" :
{"$in" : [ 1960 , 15111 , 5186 , 5371 , 756 , 1015 , 1018 , 338 , 325 , 776 , 3900 , ..., 2473] }
}
},
{"$group" :
{ "_id" : "$compound_cid" ,
"fingerprintmatches" : {"$sum" : 1} ,
"totalcount" : { "$first" : "$fingerprint_count"} ,
"smiles" : {"$first" : "$smiles"}
}
},
{"$project" :
{ "_id" : 1 ,
"tanimoto" : {"$divide" : ["$fingerprintmatches"] , { "$subtract" : [ { "$add" : [ 89 , "$totalcount"]} , "$fingerprintmatches"] }. ] } ,
"smiles" : 1
}
},
{"$match" :
{"tanimoto" : {"$gte" : 0.05} }
} ]
}

Đầu ra của đường ống này chứa danh sách các kết nối có Tanimoto 0.8 hoặc cao hơn liên quan đến kết nối đích cụ thể. Có thể tìm thấy hình ảnh minh họa của băng tải này dưới đây:

3. Kết luận

Cấu trúc tổng hợp MongoDB mới cung cấp một tập hợp các toán tử dễ sử dụng cho phép người dùng diễn đạt các thuật toán của loại rút gọn thẻ một cách ngắn gọn hơn. Khái niệm về băng tải bên dưới nó cung cấp một cách trực quan để xử lý dữ liệu.

Không có gì ngạc nhiên khi mô hình đường ống này được áp dụng bởi các phương pháp tiếp cận NoSQL khác nhau, bao gồm Gremlin Framework Tinkerpop trong quá trình triển khai và Cypher Neo4j trong việc triển khai.

Về mặt hiệu suất, giải pháp đường ống là một cải tiến đáng kể trong việc thực hiện các bản đồ giảm thiểu.

Các nhà khai thác ban đầu được hỗ trợ bởi nền tảng MongoDB, dẫn đến cải thiện hiệu suất đáng kể so với Javascript được thông dịch. Vì Khung tổng hợp cũng có thể hoạt động trong môi trường cô lập, nên nó dễ dàng vượt quá hiệu suất của quá trình triển khai ban đầu của tôi, đặc biệt khi số lượng kết nối đầu vào nhiều và mục tiêu Tanimoto thấp. Hiệu suất tuyệt vời từ lệnh MongoDB!

Tổng hợp | MongoDB | Hướng dẫn


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Giới hạn kích thước tài liệu đơn MongoDB là 16MB

  2. Tạo chỉ mục văn bản với các trọng lượng trường khác nhau trong MongoDB

  3. nhiều phiên bản của Mongo DB trên cùng một máy chủ

  4. Toán tử tổng hợp MongoDB $ count

  5. Chỉ trả về các phần tử tài liệu con đã khớp trong một mảng lồng nhau