JON*_*JON 5 pagination mongoose mongodb node.js
我是Node js和MongoDB的新手。我正在努力进行良好的MongoDB搜索和分页,但是性能存在问题。计算和搜索记录花费了太多时间。
如果我使用小字词进行搜索,则它的运行速度会更快;如果我使用“长字符串”或“数据库中无记录”,则它会花费太多时间,即50到186.30秒。(这是太多时间,我希望它是1到2秒)。
我的记录中有超过15,00,000个数据。
如果我不包括搜索词的数量。它花费了0.20到1.5秒,但是当我在搜索单词时对记录进行计数时,它花费了25.0到35.0秒。
我不知道如何减少用搜索词(查询优化)来计数记录的时间。
我尝试了查询优化的最大级别。
我也尝试过
{
$count: "passing_scores"
}
Run Code Online (Sandbox Code Playgroud)
但时间没有变化。我被卡住了。我必须减少搜索词的计数时间。
以SQL查询为例
SELECT * FROM `post`
Left JOIN catagory ON post.catid=catagory.id
WHERE post_name LIKE '%a%' OR post_data LIKE '%a%' OR tags LIKE '%a%' OR post_url LIKE '%a%'
Run Code Online (Sandbox Code Playgroud)
NODE和MongoDB
PostObj.count({},function(err,totalCount) {
if(err) {
response = {"error" : true,"message" : "Error fetching data"}
}
PostObj.aggregate([
{ $lookup:
{
from: 'catagories',
localField: 'catagory.catagory_id',
foreignField: '_id',
as: 'catagories_data'
}
},
{
$match:
{
$or: [
{"catagories_data.catagory_name": { $regex: new RegExp(search_data)}},
{"postname": { $regex: new RegExp(search_data) }},
{"posturl": { $regex: new RegExp(search_data) }},
{"postdata": { $regex: new RegExp(search_data) }},
{"tags": { $regex: new RegExp(search_data) }}
]
}
},
{ $limit : search_limit },
{ $skip : search_skip },
{ $group : { _id : "$_id", postname: { $push: "$postname" } , posturl: { $push: "$posturl" } } }
]).exec(function (err, data){
//end insert log data
if(err) {
response = {"error" : true,"message" :err};
}
if(search_data != "")
{
// count record using search word
PostObj.aggregate([
{ $lookup:
{
from: 'catagories',
localField: 'catagory.catagory_id',
foreignField: '_id',
as: 'catagories_data'
}
},
{
$match:
{
$or: [
{"catagories_data.catagory_name": { $regex: new RegExp(search_data)}},
{"postname": { $regex: new RegExp(search_data) }},
{"posturl": { $regex: new RegExp(search_data) }},
{"postdata": { $regex: new RegExp(search_data) }},
{"tags": { $regex: new RegExp(search_data) }}
]
}
},
{ $group: { _id: null, myCount: { $sum: 1 } } },
{ $project: { _id: 0 } }
]).exec(function (err, Countdata){
res.json({
sEcho : req.body.draw,
iTotalRecords: Countdata.myCount,
iTotalDispla,yRecords: Countdata.myCount,
aaData: data
});
}
res.json({
sEcho : req.body.draw,
iTotalRecords: totalPages,
iTotalDisplayRecords: totalPages,
aaData: data
});
});
});
Run Code Online (Sandbox Code Playgroud)
另外,我必须尝试这种方式,但比第一个代码多了35.0至49.0秒。
PostObj.aggregate([
{ $lookup:
{
from: 'catagories',
localField: 'catagory.catagory_id',
foreignField: '_id',
as: 'catagories_data'
}
},
{
$match:
{
$or: [
{"catagories_data.catagory_name": { $regex: new RegExp(search_data)}},
{"postname": { $regex: new RegExp(search_data) }},
{"posturl": { $regex: new RegExp(search_data) }},
{"postdata": { $regex: new RegExp(search_data) }},
{"tags": { $regex: new RegExp(search_data) }}
]
}
},
{ '$facet' : {
metadata: [ { $count: "total" }, { $addFields: { page: NumberInt(3) } } ],
data: [ { $skip: 20 }, { $limit: 10 } ] // add projection here wish you re-shape the docs
} }
] )
Run Code Online (Sandbox Code Playgroud)
如果我不使用搜索词,那就很好。搜索任何单词时出现问题(该工作的记录数没有跳过和限制)
收集资料
发布
{
"_id": ObjectId("5d29bd7609f28633f38ccc13"),
"postname": "this is some data ",
"tags " : "
Damita,
Caro,
Leontyne,
Theodosia,
Vyky ",
"postdata ": "Berry Samara Kellia Rebekah Linette Hyacinthie Joelly Micky Tomasina Christian Fae Doralynn Chelsea Aurie Gwendolyn Tate
Cairistiona Ardys Aubrie Damita Olga Kelli Leone Marthena Kelcy
Cherlyn Molli Pris Ginelle Sula Johannah Hedwig Adelle Editha Lindsey
Loleta Lenette Ann Heidie Drona Charlena Emilia Manya Ketti Dorthea
Jeni Lorene Eolanda Karoly Loretta Marylou Tommie Leontyne Winny Cyb
Violet Pavia Karen Idelle Betty Doloritas Judye Aretha Quinta Billie
Vallie Fiona Letty Gates Shandra Rosemary Dorice Doro Coral Tove Crin
Bobbe Kristan Tierney Gianina Val Daniela Kellyann Marybeth Konstance
Nixie Andeee Jolene Patrizia Carla Arabella Berna Roseline Lira Cristy
Hedi Clem Nerissa ",
"catagory " : [
{ "catagory_id " : [ ObjectId("5d29bd7509f28633f38ccbfd")]},
{ "catagory_id": [ ObjectId("5d29bd7509f28633f38ccbfd") ]}],
"createby": "5d22f712fe481b2a9afda4aa"
}
Run Code Online (Sandbox Code Playgroud)
类别
{
"_id": ObjectId("5d29bc271a68fb333531f6a1"),
"catagory_name": "Katharine",
"catagory_description": "Katharine"
}
Run Code Online (Sandbox Code Playgroud)
有什么解决办法吗?
如果在您的情况下,您的正则表达式只是寻找一个(或几个)单词,那么最好使用$text而不是 $regex。$text 可以使用文本索引,因此速度更快。就 MySQL 而言, $text 是 LIKE , $regex 是 REGEXP。由于在您的示例 mysql 查询中您使用的是 LIKE,因此我非常有信心您也可以在 mongo 查询中使用 $text 而不是 $regex。
您需要(如果还没有)在您的字段上有一个复合“文本”索引 - (postname、tags、postdata 和 posturl)。
db.POST.createIndex(
{
postname: "text",
tags: "text",
posturl: "text",
postdata: "text"
}
)
Run Code Online (Sandbox Code Playgroud)
我可以建议您尝试一些技巧。
1:POST收藏
看来您只存储category_id在category对象属性数组中,您应该避免这种情况。相反,你应该做的是如下。
post_id在集合中创建新属性,而不是在[高性能方法]中创建category类别对象数组。post collection
或者
category将对象的后收集形式数组的属性转换为简单数组。[平均表现]。
Ex: category: [ ObjectId("5d29bd7509f28633f38ccbfd", ObjectId("5d29bd7509f28633f38ccbfd", ObjectId("5d29bd7509f28633f38ccbfd"];
肯定在这两种情况post_id下都 category必须对属性进行索引。
2:查找
lookup您应该使用pipeline方法而不是使用简单的管道
例如:
不好。
$lookup:{
from: 'catagories',
localField: 'catagory.catagory_id', // BAD IDEA //
foreignField: '_id',
as: 'catagories_data'
},
Run Code Online (Sandbox Code Playgroud)
好的。
$lookup:{
from: 'catagories',
localField: '_id',
foreignField: 'post_id', // GOOD IDEA
as: 'catagories_data'
},
Run Code Online (Sandbox Code Playgroud)
更好
$lookup:{
let : { post_id: "$_id" },
from: 'catagories',
pipeline:[
{
$match: {
$expr: {
$and: [
{ $eq: ["$post_id", "$$post_id"], },
]
}
},
},
{
$match: {
$or: [
// AVOID `new` keyword if you can do such;
// and create indexes for the same;
{ "catagory_name": { $regex: `^${search_data}` } },
{ "postname": { $regex: `^${search_data}` } },
{ "posturl": { $regex: `^${search_data}` } },
{ "postdata": { $regex: `^${search_data}` } },
{ "tags": { $regex: `^${search_data}` } }
]
}
}
],
as: 'catagories_data'
},
Run Code Online (Sandbox Code Playgroud)
毕竟facet pipeline seems fine to me.
'$facet' : {
metadata: [ { $count: "total" }, { $addFields: { page: NumberInt(3) } } ],
data: [ { $skip: 20 }, { $limit: 10 } ] // add projection here wish you re-shape the docs
}
Run Code Online (Sandbox Code Playgroud)
减慢查询的其他方面取决于
完整的查询将如下所示
PostObj.aggregate([
{
$lookup: {
let: { post_id: "$_id" },
from: 'categories',
pipeline: [
{
$match: {
$expr: {
$and: [
{ $eq: ["$post_id", "$$post_id"], },
]
}
},
},
{
$match: {
$or: [
// AVOID `new` keyword if you can do such;
// and create indexes for the same;
{ "catagory_name": { $regex: `^${search_data}` } },
{ "postname": { $regex: `^${search_data}` } },
{ "posturl": { $regex: `^${search_data}` } },
{ "postdata": { $regex: `^${search_data}` } },
{ "tags": { $regex: `^${search_data}` } }
]
}
}
],
as: "catagories_data"
}
},
{
'$facet': {
metadata: [{ $count: "total" }, { $addFields: { page: NumberInt(3) } }],
catagories_data: [{ $skip: 0 }, { $limit: 10 }]
}
}
])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
265 次 |
| 最近记录: |