3

好的,MongoDB专家,请看一下我的收藏:

[{
  "_id" : "item_0",
  "Name" : "Item 0",
  "Description" : "Some description for this item...",
  "Properties" : {
    "a" : 5.0,
    "b" : 0.0,
    "c" : 6.0,
    "d" : 6.0,
    "e" : 2.0,
    "f" : 0.0,
    "g" : 9.0,
    "h" : 3.0,
    "i" : 4.0,
    "j" : 5.0
  }
},
{ // 5.000-10.000 more items... }
]

我正在使用这个聚合来乘以一组选定的属性(在本例中为 a、b、c 和 d),然后按它们的乘积对它们进行排序:

{
    "aggregate": "item",
    "pipeline": [
        {
            "$project": {
                "_id": 1,
                "Name": 1,
                "s": {
                    "$multiply": [
                        "$Properties.a",
                        "$Properties.b",
                        "$Properties.c",
                        "$Properties.d"
                    ]
                }
            }
        },
        {
            "$sort": {
                "s": -1
            }
        },
        {
            "$limit": 100
        }
    ]
}

现在这一切都很好,但是当项目和属性的数量增加时,执行聚合的时间会增加很多!

有没有更好的方法(更有效)来实现这样的目标?搜索最高的产品(一组属性的倍数)必须很快。如果有办法对此进行索引,具有所有不同的属性组合并将它们缓存或其他什么?索引需要一段时间没关系,只要查询快!

感谢您在这件事上的任何帮助,我非常感谢!

4

1 回答 1

4

鉴于您对更快搜索和效率的要求,我认为更好的方法是将 Map/Reduce 与输出集合一起使用(至少在聚合框架支持使用集合作为输出之前)。

为您的用例使用输出集合有几个优点。

尤其:

  • 你可以有灵活的索引和排序
  • 不必为每个查询实时计算结果
  • 您不受内联结果的 16Mb BSON 文档大小的限制

您可以使用 Map/Reduce 的merge输出选项来更新输出集合中的计算(本质上,这将是您的缓存)。

根据您的各种属性的更新频率,我将研究一种基于“上次更新”时间戳或其他一些标准的增量方法,这些标准允许您确定何时需要重新计算值。这将允许您随着收藏的增长使批量大小更易于管理。

于 2012-08-23T11:11:29.703 回答