【发布时间】:2018-03-25 23:44:00
【问题描述】:
在我的 mongodb 集合中,我有 1500 万个具有以下 json 结构的文档。每个 json 文档的 playfields 数组字段中的嵌入文档计数都会发生变化。我所有的查询都涉及根据 playfields 数组字段中的数据过滤文档。所有查询的执行时间都超过 2 分钟。
嵌入文档中的 value 字段存储多种数据类型(int、string)。这是糟糕的设计吗?
我在编写查询时做错了吗?我是否缺少任何索引?我是否必须将数据从单个文档中的嵌入文档移动到多个集合?
多条件查询(已发布)需要 3 分钟才能执行。过滤同一集合时使用的语法是否错误?我的目标是返回满足所有这些条件的文档。
如果我将查询分成几部分,则每个都需要 ms 才能执行。 1) db.playfieldvalues.find({$or:[ {playfields: {$elemMatch:{ID:"Play.NHL.NHLAwayTeam" ,value: "NYI NEW YORK ISLANDERS"}}},{playfields: {$elemMatch: {ID:“Play.NHL.NHLAwayTeam”,值:“TB TAMPA BAY LIGHTNING”}}}]}) 2) db.playfieldvalues.find({playfields: {$elemMatch:{ID:"Play.NHL.NHLHomeTeam" ,value: "BOS BOSTON BRUINS"}}}) 3) db.playfieldvalues.find({playfields: {$elemMatch:{ID:"Play.NHL.NHLEventX" ,value: {$gt: 0, $lt: 25}}}}) 4) db.playfieldvalues.find({playfields: {$elemMatch:{ID:"Play.NHL.NHLEventScoreDifferential" ,value: {$gt: 0}}}})
已创建索引:
db.collection.ensureIndex({ "playfields.ID": 1, "playfields.value": 1 })
正在运行的查询:
1:
db.playfieldvalues.find({playfields: {$elemMatch:{ID:"Play.NHL.NHLHomeTeam" ,value: "BOS BOSTON BRUINS"}}})
2:
db.playfieldvalues.find({$and:[
{playfields: {$elemMatch:{ID:"Play.NHL.NHLHomeTeam" ,value: "BOS BOSTON BRUINS"}}},
{$or:[ {playfields: {$elemMatch:{ID:"Play.NHL.NHLAwayTeam" ,value: "NYI NEW YORK ISLANDERS"}}},{playfields: {$elemMatch:{ID:"Play.NHL.NHLAwayTeam" ,value: "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}}}}
]
})
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"
}
]
}
【问题讨论】:
-
我是第一次使用 Mongodb。我正在阅读有关索引和尝试的文章,但没有突破。任何人都可以就这个问题给我建议。
-
您使用的是哪个版本的 MongoDB?您使用的是 WiredTiger 存储引擎吗?另外我会在查询末尾添加 .explain() 。示例:db.playfieldvalues.find({playfields: {$elemMatch:{ID:"Play.NHL.NHLHomeTeam" ,value: "BOS BOSTON BRUINS"}}}).explain();如果获胜计划阶段是 FETCH,IXSCAN 则意味着它使用您的索引。你也可以在这里查看文档docs.mongodb.com/manual/reference/explain-results
-
mongodb 版本:3.4.9 WiredTiger 存储引擎:不知道。如何检查。我下载了 mongodb 安装程序并将其安装在 windows server 2012 操作系统上。我运行了解释功能,我不知道如何解释它。将发布有问题的解释结果
-
如何衡量执行时间?您的客户端和服务器之间是否存在慢速网络?
-
第二次查询的执行时间 4.6 分钟。我直接在服务器上运行。没有网络问题。
标签: json mongodb nosql nosql-aggregation