我们正在评估方面计算方面的ArangoDB性能。
还有许多其他产品可以通过特殊的API或查询语言执行相同的操作:


MarkLogic方面
ElasticSearch聚合
Solr Faceting等


我们知道,Arango中没有专门的API可以显式计算事实。
但实际上,它不是必需的,这要归功于全面的AQL,它可以通过简单的查询轻松实现,例如:

 FOR a in Asset
  COLLECT attr = a.attribute1 INTO g
 RETURN { value: attr, count: length(g) }


此查询在attribute1上计算一个构面,并产生以下形式的频率:

[
  {
    "value": "test-attr1-1",
    "count": 2000000
  },
  {
    "value": "test-attr1-2",
    "count": 2000000
  },
  {
    "value": "test-attr1-3",
    "count": 3000000
  }
]


就是说,在我的整个集合中,attribute1采取三种形式(test-attr1-1,test-attr1-2和test-attr1-3),并提供了相关计数。
我们几乎运行了一个DISTINCT查询和汇总计数。

看起来简单干净。只有一个,但真正重要的问题-性能。

上面提供的查询运行了31秒!仅包含8M个文档的测试集合。
我们尝试了不同的索引类型,存储引擎(使用rocksdb和不使用rocksdb),无济于事地研究了说明计划。
我们在此测试中使用的测试文档非常简洁,只有三个简短的属性。

在此,我们将不胜感激。
我们要么做错了事。或ArangoDB根本不旨在在此特定区域执行。

顺便说一句,最终目标是在不到一秒的时间内运行以下内容:

LET docs = (FOR a IN Asset

  FILTER a.name like 'test-asset-%'

  SORT a.name

 RETURN a)

LET attribute1 = (

 FOR a in docs

  COLLECT attr = a.attribute1 INTO g

 RETURN { value: attr, count: length(g[*])}

)

LET attribute2 = (

 FOR a in docs

  COLLECT attr = a.attribute2 INTO g

 RETURN { value: attr, count: length(g[*])}

)

LET attribute3 = (

 FOR a in docs

  COLLECT attr = a.attribute3 INTO g

 RETURN { value: attr, count: length(g[*])}

)

LET attribute4 = (

 FOR a in docs

  COLLECT attr = a.attribute4 INTO g

 RETURN { value: attr, count: length(g[*])}

)

RETURN {

  counts: (RETURN {

    total: LENGTH(docs),

    offset: 2,

    to: 4,

    facets: {

      attribute1: {

        from: 0,

        to: 5,

        total: LENGTH(attribute1)

      },

      attribute2: {

        from: 5,

        to: 10,

        total: LENGTH(attribute2)

      },

      attribute3: {

        from: 0,

        to: 1000,

        total: LENGTH(attribute3)

      },

      attribute4: {

        from: 0,

        to: 1000,

        total: LENGTH(attribute4)

      }

    }

  }),

  items: (FOR a IN docs LIMIT 2, 4 RETURN {id: a._id, name: a.name}),

  facets: {

    attribute1: (FOR a in attribute1 SORT a.count LIMIT 0, 5 return a),

    attribute2: (FOR a in attribute2 SORT a.value LIMIT 5, 10 return a),

    attribute3: (FOR a in attribute3 LIMIT 0, 1000 return a),

    attribute4: (FOR a in attribute4 SORT a.count, a.value LIMIT 0, 1000 return a)

   }

}


谢谢!

最佳答案

原来ArangoDB Google Group上发生了主线程。
这是一个link to a full discussion

以下是当前解决方案的摘要:


从已完成许多性能改进的特定功能分支运行Arango的自定义版本(希望他们尽快将其发布到主要版本中)
构面计算不需要索引
MMFiles是首选的存储引擎
AQL应该使用“ COLLECT attr = a.attributeX WITH COUNT INTO length”而不是“ count:length(g)”来编写
应该将AQL分成较小的部分并并行运行(我们正在运行Java8的Fork / Join来扩展方面AQL,然后将它们合并为最终结果)
一个用于过滤/排序和检索主实体的AQL(如果需要,在排序/过滤时添加相应的跳过列表索引)
对于每个构面值/频率对,其余的都是小的AQL


最后,与上面提供的原始AQL相比,我们获得了> 10倍的性能提升。

07-24 20:10