Nat*_*ner 6 query-optimization graph-databases arangodb aql
我的部分图表是使用两个大型集合之间的巨型连接构建的,每次我将文档添加到任一集合时都会运行它.该查询基于较旧的帖子.
FOR fromItem IN fromCollection
FOR toItem IN toCollection
FILTER fromItem.fromAttributeValue == toItem.toAttributeValue
INSERT { _from: fromItem._id, _to: toItem._id, otherAttributes: {}} INTO edgeCollection
Run Code Online (Sandbox Code Playgroud)
这需要大约55,000秒才能完成我的数据集.我绝对欢迎提出更快的建议.
但我有两个相关的问题:
upsert没关系,但在这种情况下,因为我无法预先知道密钥,所以对我没有帮助.为了获得前面的密钥,我需要通过示例查询以找到其他相同的现有边的密钥.这似乎是合理的,只要它不会破坏我的性能,但我不知道如何在AQL中有条件地构造我的查询,以便在等效边缘尚不存在的情况下插入边缘,但如果等效边缘则不执行任何操作确实存在.我怎样才能做到这一点?如果您在没有任何索引的情况下运行查询,则必须执行两次嵌套的完整集合扫描,这可以通过查看输出来看出
db._explain(<your query here>);
它显示如下:
1 SingletonNode 1 * ROOT
2 EnumerateCollectionNode 3 - FOR fromItem IN fromCollection /* full collection scan */
3 EnumerateCollectionNode 9 - FOR toItem IN toCollection /* full collection scan */
4 CalculationNode 9 - LET #3 = (fromItem.`fromAttributeValue` == toItem.`toAttributeValue`) /* simple expression */ /* collections used: fromItem : fromCollection, toItem : toCollection */
5 FilterNode 9 - FILTER #3
...
Run Code Online (Sandbox Code Playgroud)
如果你这样做
db.toCollection.ensureIndex({"type":"hash", fields ["toAttributeValue"], unique:false})`
Run Code Online (Sandbox Code Playgroud)
然后将会有一个完整的表集合扫描,fromCollection并且对于每个项目,发现其中有一个哈希查找toCollection,这将更快.一切都会分批进行,所以这应该已经改善了局面.在db._explain()将显示此:
1 SingletonNode 1 * ROOT
2 EnumerateCollectionNode 3 - FOR fromItem IN fromCollection /* full collection scan */
8 IndexNode 3 - FOR toItem IN toCollection /* hash index scan */
Run Code Online (Sandbox Code Playgroud)
要仅处理最近插入的项目fromCollection相对简单:只需将导入时间的时间戳添加到所有顶点,并使用:
FOR fromItem IN fromCollection
FILTER fromItem.timeStamp > @lastRun
FOR toItem IN toCollection
FILTER fromItem.fromAttributeValue == toItem.toAttributeValue
INSERT { _from: fromItem._id, _to: toItem._id, otherAttributes: {}} INTO edgeCollection
Run Code Online (Sandbox Code Playgroud)
当然,在timeStamp属性中放入一个skiplist索引fromCollection.
这应该可以很好地发现它中的新顶点fromCollection.它将"忽略" toCollection与旧顶点链接的新顶点fromCollection.
您可以通过交换查询中的fromCollection和/ 的角色来发现这些toCollection(不要忘记fromAttributeValuein中的索引fromCollection)并记住只有在顶点是旧的时才放入边缘,如:
FOR toItem IN toCollection
FILTER toItem.timeStamp > @lastRun
FOR fromItem IN fromCollection
FILTER fromItem.fromAttributeValue == toItem.toAttributeValue
FILTER fromItem.timeStamp <= @lastRun
INSERT { _from: fromItem._id, _to: toItem._id, otherAttributes: {}} INTO edgeCollection
Run Code Online (Sandbox Code Playgroud)
这两个一起应该做你想要的.请在这里找到完整的例子.