我们正在评估ArangoDB在facets计算方面的性能。有许多其他产品可以通过特殊API或查询语言来完成相同的任务,例如:
这个查询计算属性1的分面,并以以下形式呈现频率:
它表示,在我的整个集合中,attribute1 有三种形式(test-attr1-1、test-attr1-2 和 test-attr1-3),并提供了相关的计数。基本上,我们运行了一个去重查询和聚合计数。
看起来很简单、干净。但只有一个非常大的问题——性能。
在仅有 800 万个文档的测试集合中,上述查询需要花费 31 秒的时间。我们尝试了不同的索引类型、存储引擎(包括 rocksdb 和非 rocksdb),并调查了解释计划,但均无果。
我们在此处将不胜感激地接受任何意见。要么我们做错了什么,要么 ArangoDB 简单地没有被设计成在这个特定领域中执行。
顺便说一下,最终目标是在不到一秒钟的时间内运行类似以下内容的查询:
- MarkLogic Facets
- ElasticSearch Aggregations
- Solr Faceting等
FOR a in Asset
COLLECT attr = a.attribute1 INTO g
RETURN { value: attr, count: length(g) }
这个查询计算属性1的分面,并以以下形式呈现频率:
[
{
"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),并提供了相关的计数。基本上,我们运行了一个去重查询和聚合计数。
看起来很简单、干净。但只有一个非常大的问题——性能。
在仅有 800 万个文档的测试集合中,上述查询需要花费 31 秒的时间。我们尝试了不同的索引类型、存储引擎(包括 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)
}
}
谢谢!