當我使用 mongodb 查詢時$in,當專案長度很小時,它很快。但是當我查詢大專案時,它很慢。
如何提高性能?
例如:
我有 2 個集合:
- 圖書
for(var i = 0 ; i < 1000000; i ) {
db.books.insert({name: "book" i})
}
- 用戶。比方說,user1 只能查詢bucket 中_id 所在的書籍,所以當我們找到user1 的書籍串列時,我們會這樣查詢:
// a. find all books ids that user1 can see,
books: db.user_access.findOne({uid: "user1"},{books: 1});
// books: ["id1","id2","id3" ... "idN"]
// b. query with the access.
db.books.find({$in: {_id: books}}).limit(10).skip(0) // pagination.
我們10從具有復雜條件的大型集合中查詢檔案。我們如何從設計或查詢提高性能?
uj5u.com熱心網友回復:
在向資料庫發送查詢之前限制和跳過應用程式中的圖書串列。先只發送book1~book10,然后再發送book11~book12,以此類推。
使用Keyset Pagination,告訴最后獲取的專案是什么,并獲取該專案之后的下一頁。
uj5u.com熱心網友回復:
我有作業代碼,會給你一些解釋:
const { MongoClient } = require('mongodb')
const uri = 'mongodb://127.0.0.1:27017/';
const dbName = 'stackoverflow_q69548755';
const client = new MongoClient(uri);
async function run(callback) {
try {
await client.connect();
console.log('Connected successfully to server');
await callback();
} finally {
await client.close();
console.log('Connection closed')
}
}
async function runOperation() {
const db = client.db(dbName);
// users and user_books (from a cart) should go in different collections
// ! collections can be accessed later via api like: db.user_access..., db.books...
const usersCollection = db.collection('user_access'); // user details with books assigned
const booksCollection = db.collection('books');
const books = [];
const userBooks = [];
const totalBooks = 1000000;
const totalUserBooks = 10;
// * create user
const userDocument = await usersCollection.insertOne({ uid: 'user1' });
console.log(`User ${userDocument.insertedId} created`)
// * create books
for (let i = 0 ; i < totalBooks; i ) {
books.push({ name: "book" i });
}
const bookDocuments = await booksCollection.insertMany(books);
console.log(`${books.length} books created`)
// * assign a few books to the user
const bookDocumentIds = Object.values(bookDocuments.insertedIds);
for (let i = 0; i < totalUserBooks; i ) {
userBooks.push(bookDocumentIds[pickRandomBook(totalBooks)]);
}
await usersCollection.updateOne(
{ _id: userDocument.insertedId },
{ $set: { books: userBooks }}
);
console.log(`User took ${totalUserBooks} books randomly from ${totalBooks} in the collection:\n\t${userBooks.join(', ')}`)
// * find user books from books collection
// we know which books are from the user!
const bookFilteredDocuments = await booksCollection.find(
{ _id: { $in: userBooks } }
).skip(0).limit(totalUserBooks).toArray();
const bookFilteredDocumentIds = bookFilteredDocuments.map(document => document._id);
console.warn(`Books filtered: \n\t${bookFilteredDocumentIds.join(', ')}`)
console.log('Done');
}
function pickRandomBook(maxBooks) {
// expected outputs are [0, 1, ..., maxBooks - 1]
return Math.floor(Math.random() * maxBooks);
}
run(runOperation).catch(console.dir);
我想您正在使用MongoClient來訪問您的收藏。我在代碼中留下了一些注釋,但也會在這里寫下一些東西:
使用
find()過濾器時,filter引數需要屬性名稱,然后是 operator,例如{_id: {$in: books}}代替{$in: {_id: books}}使用分頁時,操作順序為:
- 種類
- 跳過
- 限制
您交換了跳過和限制操作的順序。
不知道為什么您站點上的查詢如此緩慢,但是我在我的機器上使用本地資料庫在本地運行它,我在一兩秒鐘內得到了結果。我建議你分析我的代碼。我認為主要問題在于我指出的第一條評論。如果您的查詢速度太慢,例如超過一兩秒鐘,您能更具體嗎?- 如果我的解決方案對您有幫助,請寫下究竟是什么對您有幫助。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/314295.html
標籤:MongoDB
