如何使用mongoDB作为搜索引擎?
我尝试使用mongoDB作为搜索引擎,并意识到这是一场灾难。我尝试对500万个地理位置文档进行简单查询如何使用mongoDB作为搜索引擎?,mongodb,Mongodb,我尝试使用mongoDB作为搜索引擎,并意识到这是一场灾难。我尝试对500万个地理位置文档进行简单查询 db.runCommand( { dropDatabase: 1 } ) db.createCollection("places"); db.places.createIndex( { "locs.loc" : "2dsphere" } ) function randInt(n) { return parseInt(Math.random()*n); } function randF
db.runCommand( { dropDatabase: 1 } )
db.createCollection("places");
db.places.createIndex( { "locs.loc" : "2dsphere" } )
function randInt(n) { return parseInt(Math.random()*n); }
function randFloat(n) { return Math.random()*n; }
for(var j=0; j<10; j++) {
print("Building op "+j);
var bulkop=db.places.initializeOrderedBulkOp() ;
for (var i = 0; i < 1000000; ++i) {
bulkop.insert(
{
locs: [
{
loc : {
type: "Point",
coordinates: [ randFloat(180), randFloat(90) ]
}
},
{
loc : {
type: "Point",
coordinates: [ randFloat(180), randFloat(90) ]
}
}
]
}
)
};
print("Executing op "+j);
bulkop.execute();
}
需要4分钟才能返回
"waitedMS" : NumberLong(0),
"results" : [ ],
"stats" : {
"nscanned" : 10018218,
"objectsLoaded" : 15000000,
"maxDistance" : 0,
"time" : 219873
},
"ok" : 1
例如,在somethink-like sphinx索引上进行的相同查询(实际上,对于此类查询根本不使用索引,只需滚动内存中已经存在的所有记录即可过滤它们)返回200 ms
db.runCommand(
{
geoNear: "places",
near: { type: "Point", coordinates: [ 73.9667, 40.78 ] },
spherical: true,
query: {category: "private"},
maxDistance: 1000000
}
)
我做错了什么?他们的计算机上有32GB的可用内存,所有数据仅使用150MB。他们有没有办法加快mongoDB的速度?或者说,我们不能将mongoDB用作搜索引擎?mongoDB 3.4rc,有2mln记录 我认为代码的问题与'query'参数有关,因为您正在对没有索引的集合进行另一次查询 更新(带有结果/统计数据):
db.runCommand( { dropDatabase: 1 } )
db.createCollection("places");
db.places.createIndex( { "locs.loc.coordinates" : "2dsphere" } )
function randInt(n) { return parseInt(Math.random()*n); }
function randFloat(n) { return Math.random()*n; }
for(var j=0; j<10; j++) {
print("Building op "+j);
var bulkop=db.places.initializeOrderedBulkOp() ;
for (var i = 0; i < 1000000; ++i) {
bulkop.insert(
{
locs: [
{
loc : {
type: "Point",
coordinates: [ randFloat(180), randFloat(90) ]
}
},
{
loc : {
coordinates: [ randFloat(180), randFloat(90) ]
}
}
]
}
)
};
print("Executing op "+j);
bulkop.execute();
}
58ms:
2ms第二次运行:
156996ms:
创建“类别”索引后:
{locs.loc.coordinates:“2dsphere”,类别:1}
13562ms:
更新:
通过添加“maxDistance”,您可以执行396msvs6863ms
db.runCommand(
{
geoNear: "places",
near: { type: "Point", coordinates: [ 73.9667, 40.78 ] },
spherical: true,
query: {category: "private"},
maxDistance: 1000000
}
)
最大距离:1000000
"stats" : {
"nscanned" : NumberInt(107820),
"objectsLoaded" : NumberInt(1),
"avgDistance" : 938598.1782650856,
"maxDistance" : 938598.1782650856,
"time" : NumberInt(396)
}
没有“maxDistance”:
资料来源:
更重要的是,您的查询使用了“坐标数组”,我认为这是无用的,因为一个对象(通常)有一个地理位置点
另一种优化方法是使用“geoinsin”,因为它不是按“距离”排序的(也许你想按“投票最多的餐厅”排序)。根据场景而定。MongoDB 3.4rc,具有2mln记录 我认为代码的问题与'query'参数有关,因为您正在对没有索引的集合进行另一次查询 更新(带有结果/统计数据):
db.runCommand( { dropDatabase: 1 } )
db.createCollection("places");
db.places.createIndex( { "locs.loc.coordinates" : "2dsphere" } )
function randInt(n) { return parseInt(Math.random()*n); }
function randFloat(n) { return Math.random()*n; }
for(var j=0; j<10; j++) {
print("Building op "+j);
var bulkop=db.places.initializeOrderedBulkOp() ;
for (var i = 0; i < 1000000; ++i) {
bulkop.insert(
{
locs: [
{
loc : {
type: "Point",
coordinates: [ randFloat(180), randFloat(90) ]
}
},
{
loc : {
coordinates: [ randFloat(180), randFloat(90) ]
}
}
]
}
)
};
print("Executing op "+j);
bulkop.execute();
}
58ms:
2ms第二次运行:
156996ms:
创建“类别”索引后:
{locs.loc.coordinates:“2dsphere”,类别:1}
13562ms:
更新:
通过添加“maxDistance”,您可以执行396msvs6863ms
db.runCommand(
{
geoNear: "places",
near: { type: "Point", coordinates: [ 73.9667, 40.78 ] },
spherical: true,
query: {category: "private"},
maxDistance: 1000000
}
)
最大距离:1000000
"stats" : {
"nscanned" : NumberInt(107820),
"objectsLoaded" : NumberInt(1),
"avgDistance" : 938598.1782650856,
"maxDistance" : 938598.1782650856,
"time" : NumberInt(396)
}
没有“maxDistance”:
资料来源:
更重要的是,您的查询使用了“坐标数组”,我认为这是无用的,因为一个对象(通常)有一个地理位置点
另一种优化方法是使用“geoinsin”,因为它不是按“距离”排序的(也许你想按“投票最多的餐厅”排序)。根据场景不同。删除“查询”,在我的计算机上,我可以在1mln记录上获得6ms。{“nscaned”:117,“objectsLoaded”:59,“avgDistance”:0.001017138667266944,“maxDistance”:0.0016776194783600408,“time”:2}谢谢,但目的正是为了不删除“查询”:(因为在运行查询之前,你不知道它是否会匹配一些记录…这里的想法是模拟一个没有(或很少)返回记录的查询。4分钟后,你应该有一个索引,然后删除“查询”,在我的计算机上,我可以在1mln记录上得到6ms。{“nscanned”:117,“objectsLoaded”:59,“avgDistance”:0.001017138667266944,“maxDistance”:0.0016776194783600408,“time”:2}Daniele,谢谢,但目的正是为了不删除“query”:(因为在运行查询之前,您不知道它是否会匹配某些记录……这里的想法是模拟一个返回no(或很少)的查询记录。4分钟后,你应该有一个索引,然后看看我之前的评论,目的就是不删除“查询”:(因为在运行查询之前,你不知道它是否与一些记录匹配……这里的想法是模拟一个返回否(或很少)的查询记录。4分钟后,你会发现他们的记录不对应,这是不可接受的。你应该有一个索引,但我不能在所有可能的查询中添加索引!在sphinx上,他们没有索引,需要200毫秒才能完成return@loki你真的能解释一下你想做什么然后更新你的问题吗?你的问题看起来像是一个“大规模查询,证明MongoDB在地理定位查询方面很慢“:从我的回答中可以看出,这不是真的。现在,您要求有一个查询/架构,可以在不使用索引的情况下处理所有您想要的场景。我认为您的请求应该写得很好。好的,所以尝试运行此查询:db.runCommand({geoNear:“places”,near:{type:“Point”,坐标:[-73.9667,-40.78]},sphereal:true})..返回也需要几分钟时间:(看看我之前的评论,目的就是不删除“query”:(因为在运行查询之前,您不知道它是否与某些记录匹配……这里的想法是模拟返回no(或很少)的查询)记录。4分钟后,你会发现他们的记录不对应,这是不可接受的。你应该有一个索引,但我不能在所有可能的查询中添加索引!在sphinx上,他们没有索引,需要200毫秒才能完成return@loki你真的能解释一下你想做什么然后更新你的问题吗?你的问题看起来像是一个“大规模查询,证明MongoDB在地理定位查询方面很慢“:从我的回答中可以看出,这不是真的。现在,您要求有一个查询/架构,可以在不使用索引的情况下处理所有您想要的场景。我认为您的请求应该写得很好。好的,所以尝试运行此查询:db.runCommand({geoNear:“places”,near:{键入:“点”,坐标:[-73.9667,-40.78]},球形:true})…返回也需要几分钟:(