Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json Mongodb过滤嵌入大数组文档时的查询性能_Json_Mongodb_Nosql_Nosql Aggregation - Fatal编程技术网

Json Mongodb过滤嵌入大数组文档时的查询性能

Json Mongodb过滤嵌入大数组文档时的查询性能,json,mongodb,nosql,nosql-aggregation,Json,Mongodb,Nosql,Nosql Aggregation,在我的mongodb集合中,我有1500万个具有以下json结构的文档。每个json文档的playfields数组中嵌入的文档数都会发生变化。我的所有查询都涉及根据playfields数组中的数据过滤文档。所有查询的执行时间都超过2分钟 嵌入文档中的值字段存储多个数据类型(int、string)。这个设计不好吗 我在写问题时有没有做错什么?我是否缺少任何索引?是否必须将数据从单个文档中的嵌入文档移动到多个集合 多条件查询(有问题的发布)需要3分钟才能执行。过滤同一集合时使用的语法是否错误?我的目

在我的mongodb集合中,我有1500万个具有以下json结构的文档。每个json文档的playfields数组中嵌入的文档数都会发生变化。我的所有查询都涉及根据playfields数组中的数据过滤文档。所有查询的执行时间都超过2分钟

嵌入文档中的值字段存储多个数据类型(int、string)。这个设计不好吗

我在写问题时有没有做错什么?我是否缺少任何索引?是否必须将数据从单个文档中的嵌入文档移动到多个集合

多条件查询(有问题的发布)需要3分钟才能执行。过滤同一集合时使用的语法是否错误?我的目标是返回满足所有这些条件的文档

如果我将查询分解为多个部分,每个部分都需要ms来执行。 1) db.playfieldvalues.find({$or:[{$playfields:{$elemMatch:{ID:“Play.NHL.NHLAwayTeam”,value:“纽约岛居民”}}}}},{playfields:{$elemMatch:{ID:“Play.NHL.NHLAwayTeam”,value:“坦帕湾闪电队”}}}) 2) db.playfieldvalues.find({playfields:{$elemMatch:{ID:“Play.NHL.NHLHomeTeam”,value:“BOS BOSTON BRUINS”}}}) 3) 查找({playfields:{$elemMatch:{ID:“Play.NHL.NHLEventX”,值:{$gt:0,$lt:25}}}) 4) 查找({playfields:{$elemMatch:{ID:“Play.NHL.NHLEventScoreDifferential”,值:{$gt:0}})

已创建索引:

{ 
    "_id" : ObjectId("59dbd4c5704aa82e70ac10b5"), 
    "playid" : "2594c658-aa3b-4a98-b2eb-0cc03e4dc9e5", 
    "playfields" : [
        {
            "ID" : "Play.NHL.NHLGameDate", 
            "TS" : "", 
            "value" : NumberInt(20160228)
        }, 
        {
            "ID" : "Play.GameDate", 
            "TS" : "", 
            "value" : "2/28/2016 12:00:00 AM"
        }, 
        {
            "ID" : "Play.NHL.NHLEventType", 
            "TS" : "", 
            "value" : "HIT"
        }, 
        {
            "ID" : "Play.NHL.NHLClockTime", 
            "TS" : "", 
            "value" : "03:08"
        }, 
        {
            "ID" : "Play.NHL.NHLClockTimeSeconds", 
            "TS" : "", 
            "value" : NumberInt(188)
        }, 
        {
            "ID" : "Play.NHL.NHLEventX", 
            "TS" : "", 
            "value" : NumberInt(62)
        }, 
        {
            "ID" : "Play.NHL.NHLEventY", 
            "TS" : "", 
            "value" : NumberInt(-38)
        }, 
        {
            "ID" : "Play.NHL.NHLEventPeriod", 
            "TS" : "", 
            "value" : "1"
        }, 
        {
            "ID" : "Play.NHL.NHLGameCode", 
            "TS" : "", 
            "value" : "20933"
        }, 
        {
            "ID" : "Play.NHL.NHLSeason", 
            "TS" : "", 
            "value" : "20152016"
        }, 
        {
            "ID" : "Play.NHL.NHLHomeTeam", 
            "TS" : "", 
            "value" : "BOS BOSTON BRUINS"
        }, 
        {
            "ID" : "Play.NHL.NHLAwayTeam", 
            "TS" : "", 
            "value" : "T.B TAMPA BAY LIGHTNING"
        }, 
        {
            "ID" : "Play.NHL.NHLPrimaryTeam", 
            "TS" : "", 
            "value" : "T.B TAMPA BAY LIGHTNING"
        }, 
        {
            "ID" : "Play.NHL.NHLPrimaryTeamActionPlayer", 
            "TS" : "", 
            "value" : "e27ca5e6-d4fa-4d45-8fa2-a860f64f7ea7"
        }, 
        {
            "ID" : "Play.NHL.NHLSecondaryTeam", 
            "TS" : "", 
            "value" : "BOS BOSTON BRUINS"
        }, 
        {
            "ID" : "Play.NHL.NHLSecondaryTeamActionPlayer", 
            "TS" : "", 
            "value" : "bea1deb6-aabd-47e8-b216-6f4df5f1ea97"
        }, 
        {
            "ID" : "Play.NHL.NHLEventZone", 
            "TS" : "", 
            "value" : "DZ"
        }, 
        {
            "ID" : "Play.NHL.NHLEventScoreDifferential", 
            "TS" : "", 
            "value" : NumberInt(1)
        }, 
        {
            "ID" : "Play.NHL.NHLEventStrength", 
            "TS" : "", 
            "value" : "Even"
        }
    ]
}
db.collection.ensureIndex({“playfields.ID”:1,“playfields.value”:1})

正在运行的查询:

1:

2:

JSON文档示例:

{ 
    "_id" : ObjectId("59dbd4c5704aa82e70ac10b5"), 
    "playid" : "2594c658-aa3b-4a98-b2eb-0cc03e4dc9e5", 
    "playfields" : [
        {
            "ID" : "Play.NHL.NHLGameDate", 
            "TS" : "", 
            "value" : NumberInt(20160228)
        }, 
        {
            "ID" : "Play.GameDate", 
            "TS" : "", 
            "value" : "2/28/2016 12:00:00 AM"
        }, 
        {
            "ID" : "Play.NHL.NHLEventType", 
            "TS" : "", 
            "value" : "HIT"
        }, 
        {
            "ID" : "Play.NHL.NHLClockTime", 
            "TS" : "", 
            "value" : "03:08"
        }, 
        {
            "ID" : "Play.NHL.NHLClockTimeSeconds", 
            "TS" : "", 
            "value" : NumberInt(188)
        }, 
        {
            "ID" : "Play.NHL.NHLEventX", 
            "TS" : "", 
            "value" : NumberInt(62)
        }, 
        {
            "ID" : "Play.NHL.NHLEventY", 
            "TS" : "", 
            "value" : NumberInt(-38)
        }, 
        {
            "ID" : "Play.NHL.NHLEventPeriod", 
            "TS" : "", 
            "value" : "1"
        }, 
        {
            "ID" : "Play.NHL.NHLGameCode", 
            "TS" : "", 
            "value" : "20933"
        }, 
        {
            "ID" : "Play.NHL.NHLSeason", 
            "TS" : "", 
            "value" : "20152016"
        }, 
        {
            "ID" : "Play.NHL.NHLHomeTeam", 
            "TS" : "", 
            "value" : "BOS BOSTON BRUINS"
        }, 
        {
            "ID" : "Play.NHL.NHLAwayTeam", 
            "TS" : "", 
            "value" : "T.B TAMPA BAY LIGHTNING"
        }, 
        {
            "ID" : "Play.NHL.NHLPrimaryTeam", 
            "TS" : "", 
            "value" : "T.B TAMPA BAY LIGHTNING"
        }, 
        {
            "ID" : "Play.NHL.NHLPrimaryTeamActionPlayer", 
            "TS" : "", 
            "value" : "e27ca5e6-d4fa-4d45-8fa2-a860f64f7ea7"
        }, 
        {
            "ID" : "Play.NHL.NHLSecondaryTeam", 
            "TS" : "", 
            "value" : "BOS BOSTON BRUINS"
        }, 
        {
            "ID" : "Play.NHL.NHLSecondaryTeamActionPlayer", 
            "TS" : "", 
            "value" : "bea1deb6-aabd-47e8-b216-6f4df5f1ea97"
        }, 
        {
            "ID" : "Play.NHL.NHLEventZone", 
            "TS" : "", 
            "value" : "DZ"
        }, 
        {
            "ID" : "Play.NHL.NHLEventScoreDifferential", 
            "TS" : "", 
            "value" : NumberInt(1)
        }, 
        {
            "ID" : "Play.NHL.NHLEventStrength", 
            "TS" : "", 
            "value" : "Even"
        }
    ]
}
附上第二次查询的解释输出:

嵌入式文档中的值字段存储多个数据类型(int, 字符串)。这个设计不好吗

如果你问我个人,来自java背景,是的,这是一个糟糕的设计。但对于MongoDB来说,这并不是一个真正的问题,只要您的应用程序能够处理它。仅供参考,您的索引大小也应该相当大,您可以通过
db.playfieldvalues.stats()
检查,但这也不重要。至少它与您的性能问题无关

我在写问题时有没有做错什么

这个查询有点复杂,需要满足很多条件。 您还可以使用$or运算符将查询更改为

db.playfieldvalues.find({
$and:[
  {playfields: {$elemMatch:{ID:"Play.NHL.NHLHomeTeam" ,value: "BOS BOSTON BRUINS"}}},
  {playfields: {$elemMatch:{ID:"Play.NHL.NHLAwayTeam" ,value: {$in: ["NYI NEW YORK ISLANDERS", "T.B TAMPA BAY LIGHTNING"]}}}},
  {playfields: {$elemMatch:{ID:"Play.NHL.NHLEventY" ,value: -38}}},
  {playfields: {$elemMatch:{ID:"Play.NHL.NHLEventX" ,value: {$gt: 0}}}},
  {playfields: {$elemMatch:{ID:"Play.NHL.NHLEventScoreDifferential" ,value: {$gt: 0}}}}
  ]
})
尽量简化查询参数。甚至可以使用
.limit(n)
.skip(n)
对您来说是一个更好的解决方案

我是否缺少任何索引

看看这篇文章,尽管它很旧,但它可能是相关的。

但是,在继续删除并创建新索引之前,请尝试删除查询的某些部分,以尝试找到导致查询的确切原因。例如,我将删除以下行:

{playfields: {$elemMatch:{ID:"Play.NHL.NHLEventX" ,value: {$gt: 0}}}},
{playfields: {$elemMatch:{ID:"Play.NHL.NHLEventScoreDifferential"
,value: {$gt: 0}}}}
并检查性能是否仍然相同。查看文档docs.mongodb.com/manual/core/multikey-index-bounds。查看您的索引边界->playfields.ID和playfields.value。我不知道为什么playfields.value:(0.0,25.0)。在文档中,它说评级:{$gte:0}谓词的边界是[[0,无穷]]

我是否必须将数据从单个文档中的嵌入文档移动到 多个集合

不,你不必。没有固定的模式,您可以随心所欲

关于如何检查您是否使用wiredTiger的评论中的问题:db.serverStatus().storageEngine。但因为您使用的是mongo 3.4.9版,所以您使用的是wiredTiger

嵌入式文档中的值字段存储多个数据类型(int, 字符串)。这个设计不好吗

如果你问我个人,来自java背景,是的,这是一个糟糕的设计。但对于MongoDB来说,这并不是一个真正的问题,只要您的应用程序能够处理它。仅供参考,您的索引大小也应该相当大,您可以通过
db.playfieldvalues.stats()
检查,但这也不重要。至少它与您的性能问题无关

我在写问题时有没有做错什么

这个查询有点复杂,需要满足很多条件。 您还可以使用$or运算符将查询更改为

db.playfieldvalues.find({
$and:[
  {playfields: {$elemMatch:{ID:"Play.NHL.NHLHomeTeam" ,value: "BOS BOSTON BRUINS"}}},
  {playfields: {$elemMatch:{ID:"Play.NHL.NHLAwayTeam" ,value: {$in: ["NYI NEW YORK ISLANDERS", "T.B TAMPA BAY LIGHTNING"]}}}},
  {playfields: {$elemMatch:{ID:"Play.NHL.NHLEventY" ,value: -38}}},
  {playfields: {$elemMatch:{ID:"Play.NHL.NHLEventX" ,value: {$gt: 0}}}},
  {playfields: {$elemMatch:{ID:"Play.NHL.NHLEventScoreDifferential" ,value: {$gt: 0}}}}
  ]
})
尽量简化查询参数。甚至可以使用
.limit(n)
.skip(n)
对您来说是一个更好的解决方案

我是否缺少任何索引

看看这篇文章,尽管它很旧,但它可能是相关的。

但是,在继续删除并创建新索引之前,请尝试删除查询的某些部分,以尝试找到导致查询的确切原因。例如,我将删除以下行:

{playfields: {$elemMatch:{ID:"Play.NHL.NHLEventX" ,value: {$gt: 0}}}},
{playfields: {$elemMatch:{ID:"Play.NHL.NHLEventScoreDifferential"
,value: {$gt: 0}}}}
并检查性能是否仍然相同。查看文档docs.mongodb.com/manual/core/multikey-index-bounds。查看您的索引边界->playfields.ID和playfields.value。我不知道为什么playfields.value:(0.0,25.0)。在文档中,它说评级:{$gte:0}谓词的边界是[[0,无穷]]

我是否必须将数据从单个文档中的嵌入文档移动到 多个集合

不,你不必。没有固定的模式,您可以随心所欲


关于如何检查您是否使用wiredTiger的评论中的问题:db.serverStatus().storageEngine。但是因为您使用的是mongo 3.4.9版,所以您使用的是wiredTiger

我第一次使用Mongodb。我正在阅读有关索引和尝试的文章,但没有突破。有人能就这个问题给我一些建议吗?你使用的是什么版本的MongoDB?您正在使用WiredTiger存储引擎吗?我还要在查询的末尾添加.explain()。示例:db.playfieldvalues.find({playfields:{$elemMatch:{ID:“Play.NHL.NHLHomeTeam”,value:“BOS BOSTON BRUINS”}}}}).explain();如果获胜的计划阶段是FETCH,那么IXSCAN意味着它使用您的索引。你也可以看一看