所以我发现类似的问题,但不完全回答我要找的。如果这是复制品,请随意给我指一个合适的地方。你知道吗
我有一个收集这是一个“来源的真相”一些相当大的文件。我想做一些预过滤使用查询引擎之前,我得到我的主要分析。你知道吗
查询1:
仅检索以下位置的文档document.financials.entrycount文件gte 4美元。所以基本上,在一个文档中,我有一个子文档用于财务。我想用这个做过滤器。我只想返回条目数大于4的文档。你知道吗
问题2:
能够做数学,并将其与检索的数字进行比较。你知道吗
例如:
(totalAssets + totalCash) / (totalDebt + totalLiabilities) < .5
这些数字在子文档中。你知道吗
终于可以把这些结合起来了。你知道吗
下面是一个示例文件,预计只包括季度财务数据。你知道吗
{
"symbol": "AAWW",
"quarterly_financials": {
"2017-09-30": {
"cashChange": -106467000,
"cashFlow": 82299000,
"costOfRevenue": 439135000,
"currentAssets": 449776000,
"currentCash": 176280000,
"currentDebt": 196509000,
"grossProfit": 96613000,
"netIncome": -24162000,
"operatingExpense": 43690000,
"operatingGainsLosses": 378000,
"operatingIncome": 52923000,
"operatingRevenue": 535748000,
"researchAndDevelopment": None,
"shareholderEquity": 1575169000,
"totalAssets": 4687302000,
"totalCash": 175926000,
"totalDebt": 2105344000,
"totalLiabilities": None,
"totalRevenue": 535748000
},
"2017-12-31": {
"cashChange": 115584000,
"cashFlow": 136613000,
"costOfRevenue": 474565000,
"currentAssets": 587586000,
"currentCash": 291864000,
"currentDebt": 218013000,
"grossProfit": 153387000,
"netIncome": 209448000,
"operatingExpense": 46628000,
"operatingGainsLosses": -95000,
"operatingIncome": 106759000,
"operatingRevenue": 627952000,
"researchAndDevelopment": None,
"shareholderEquity": 1789856000,
"totalAssets": 4955462000,
"totalCash": 294413000,
"totalDebt": 2226999000,
"totalLiabilities": None,
"totalRevenue": 627952000
},
"2018-03-31": {
"cashChange": -161460000,
"cashFlow": 69125000,
"costOfRevenue": 498924000,
"currentAssets": 433193000,
"currentCash": 130404000,
"currentDebt": 223308000,
"grossProfit": 91090000,
"netIncome": 9612000,
"operatingExpense": 50521000,
"operatingGainsLosses": None,
"operatingIncome": 40569000,
"operatingRevenue": 590014000,
"researchAndDevelopment": None,
"shareholderEquity": 1792299000,
"totalAssets": 5016832000,
"totalCash": 136421000,
"totalDebt": 2270870000,
"totalLiabilities": None,
"totalRevenue": 590014000
},
"2018-06-30": {
"cashChange": 97525000,
"cashFlow": 106786000,
"costOfRevenue": 548491000,
"currentAssets": 565191000,
"currentCash": 227929000,
"currentDebt": 245322000,
"grossProfit": 117654000,
"netIncome": -21150000,
"operatingExpense": 47334000,
"operatingGainsLosses": None,
"operatingIncome": 70320000,
"operatingRevenue": 664531000,
"researchAndDevelopment": None,
"shareholderEquity": 1776073000,
"totalAssets": 5348343000,
"totalCash": 234280000,
"totalDebt": 2501488000,
"totalLiabilities": None,
"totalRevenue": 666145000
}
}
}
坦率地说,这里的主要问题是文档结构。归根结底,对于任何形式的数据库来说,通常都不能处理名为“by key”的“子文档”,这包括MongoDB。你知道吗
当在客户端代码中使用单个文档时,“按键查找”可能更有效,但是对于这样的自然“列表”,MongoDB使用类似“数组”或“集合”的结构工作得更好。你知道吗
聚合表达式
另一种可行的方法是使用聚合运算符(如^{} )将此表单“强制”到“自然列表”中进行处理,以便您可以按列表中的条目数进行筛选:
注意,这是使用mongodb3.6及更高版本的^{} 。如果您没有那个支持版本,但是仍然有mongodb3.4更高版本的^{} (尽管文档说3.6实际上是在那些更高版本中),那么您可以使用^{} 之类的东西来代替^{} 或常规的
find()
。你知道吗附加的计算表达式也是如此。底线是您仍然需要“数组转换”,以便实际处理和遍历那些“列表元素”。因此,如果只有那些满足条件的子条目加起来等于所需的四个,那么您将在数组元素上使用^{} 条件进行更改:
因此,在强制一个数组之后,用^{} 检查每个列表项,以确定使用^{} 和^{} 等运算符的数学表达式在何处满足^{} 的逻辑条件,然后使用^{} 运算符考虑剩余的过滤数组的“长度”。你知道吗
另请注意,^{} 本质上是将每个子文档转换为具有以下形式的列表:
这意味着您要查找的所有内容都位于新转换的“list”中每个文档的
"v"
属性(或“value”)下。"k"
属性当然是您用“sub document”表单命名的“key”。你知道吗另外,^{} 是处理属性的
null
(或Python的None
)值的要求,或者在适当的情况下处理“missing”属性。你知道吗JavaScript评估
不建议这样做,但是MongoDB不支持较新的操作符(如^{} )的另一种替代方法是在服务器上使用JavaScript求值,如处理此类逻辑的^{} 或^{} 。你知道吗
同样的原则也适用于必须先“强制”到数组形式中。(请原谅这里的“shell form”速记示例。所有其他语言的字符串):
虽然“噪音更小”这并不是真正的最佳选择,因为在服务器上评估JavaScript表达式的“成本”远远高于自然语言聚合表达式。还有一种可能性是,某些环境和服务器配置实际上根本不允许您使用这种JavaScript表达式。你知道吗
另请注意,如果您确实希望在稍后的分析阶段进行“聚合”,则需要将该逻辑考虑到} 查询表达式。你知道吗
mapReduce
,因为在聚合管道中不可能使用^{交替结构
最后,由于一切都依赖于从您的“命名键”创建列表,因此更好的方法通常是首先以这种方式构造数据(排除extended JSON format):
由于它已经是一个“列表”,您只需跳过^{} 部分(或类似的JavaScript):
使用这种结构还有很多优点,其中大多数甚至可以完全避免计算表达式,并且能够使用自然查询表达式。事实上,如果你这里的条件不是需要依赖于这样一个“filtered”条件,那么这只是一个自然查询,如果您已经在存储时预先计算了每个列表项中的数学表达式。你知道吗
因此,要获得最佳的查询性能,必须考虑“结构”,因为以任何形式评估“”都会导致集合扫描,而且成本非常高。你知道吗
因此,“使用列表”在事物是列表,而计算是“静态”的情况下,则提前执行并存储它们,而不是在运行时进行计算。你知道吗
相关问题 更多 >
编程相关推荐