AQL:一种用于存储库的综合查询语言
我们在JFrog的座右铭之一是我们是社区驱动的。在每次路线图会议上,我们都会讨论来自行业趋势的特性,以及我们经常从Artifactory社区得到的特性请求。AQL就是这样一个特性。没有人会说:“嘿,伙计们,你们为什么不构建一种超级高效的查询语言,它可以在我们的存储库中找到任何东西,并利用我们的数据库架构,这样它就会是Artifactory独有的,没有其他人可以做到。”但实际发生的情况是,我们不断收到对执行不同搜索功能的REST API调用的变体的请求。一个经典的例子是根据创建日期搜索工件。在2.2版本中,我们发布了在日期范围内创建的工件.这个REST API调用查找在您指定的日期范围内创建的工件。但后来,在收到越来越多的请求,要求按日期搜索的能力,但在不同的领域,我们发布了日期在日期范围内的工件在3.2版中。所以现在您可以根据工件的创建、修改或下载时间来搜索它们。你可以看到类似的场景基于布局的工件最新版本搜索在2.6版发布,随后发布了基于属性的工件最新版本搜索3.1.1版发布。还有更多使用更多参数和选项修饰API调用的示例。最终我们意识到有时候你可以取悦一些人,但无论我们多么想让我们的社区开心,我们都无法预测每个人都需要的所有不同功能。无论我们添加什么增强,总有人需要其他东西。
赋予权力的礼物
你知道那句古老的谚语给人一条鱼还是教他钓鱼?我们决定,正确的方法不是不断地“提供新的api”来满足越来越多的搜索需求,而是赋予社区构建任何你的集体想象力可以想象到的搜索查询的能力,因此……Artifactory查询语言诞生了。
这就是AQL的精髓。通过提供这样一种极其灵活的语言,允许您指定任意数量的搜索条件,以任何逻辑配置组合,使用任意一组过滤器并显示任意一组输出字段,我们不仅可以满足我们曾经收到的任何请求,还可以满足任何人还没有梦想过的任何未来请求。
见分晓
因此,让我们来看看AQL的实际应用,并看看实际的示例。
示例1
乔治见面。
George是DevOps经理。
乔治今天不高兴。他的开发人员抱怨说,系统变得越来越迟钝,而且充斥着许多旧的未使用的工件,他们侮辱地称之为“垃圾”,但硬件升级目前对George来说不是一个选择。
是春季大扫除的时候了。特别是来自远程存储库缓存,大型构件可以一直存在。我们真的需要那么多tb的数据吗?
首先我们去找古老的藏物,那些一年多前创建的(假设今天是2015年5月18日)。这个用AQL很简单:
物品。找到({“类型”:“文件”、“创建”:{$ lt:“2014 - 05 - 18 - t}})
注意我们如何使用比较运算符,比如"$ lt,并且我们正在利用AQL内置的默认功能,即使用“$and”组合多个标准。
但就像我奶奶常说的,“老并不意味着无用。”让我们确保不会删除任何仍在使用的工件。乔治只想删除最近六个月都没被下载过.所以让我们在我们的查询中添加另一个条件,这次使用" stat "域中的" downloads "字段:
物品。找到({“类型”:“文件”、“创建”:{$ lt:“2014 - 05 - 18 - t”},“stat.downloaded”:{$ lt:“2014 - 11 - 18 - t}})
但由于墨菲潜伏在每个角落,乔治想确保没有重要的东西被删除,所以他会这样做跳过“发布”存储库.
物品。找到({“类型”:“文件”、“创建”:{$ lt:“2014 - 05 - 18 - t”},“stat.downloaded”:{$ lt:“2014 - 11 - 18 - t”},“回购”:{" $ nmatch”:“* *”发布}})
在这里,我们添加了一个标准,即存储库名称不包括模式“*release*”。请注意,如果您的任何存储库的名称中带有“release”——但它不是一个发布存储库……它也将被跳过,您可能需要重新考虑您的命名约定。
为了让这个例子更复杂,假设乔治也想限制自己到大于1000字节的“大型”工件.
下面是最终的AQL查询,它可以在系统中找到所有符合这些标准的工件:
物品。找到({“类型”:“文件”、“创建”:{$ lt:“2014 - 05 - 18 - t”},“stat.downloaded”:{$ lt:“2014 - 11 - 18 - t”},“回购”:{" $ nmatch”:“* *发布”},“大小”:{" $ gt ": " 1000 "}})
如果你还没有流口水,让我们再看一个例子。Debian是一个很好的主题,因为它涉及到架构、组件和发行版,可以提供很好的搜索材料,但类似的场景也会出现在YUM、npm和几乎任何其他类型的组件上。
示例2
让我们找到所有Debian组件
- 是否在“可信赖的”分布中
- 下载超过1000次
- 并与amd64或i386架构相关联
我建议您用传统的搜索工具找到这些组件
使用AQL就容易多了。
items.find({”和“美元:[{”或“美元:[{”@deb。Architecture ": "i386"},{"@deb。Architecture ": "amd64"}]},{"@deb. Architecture "分配”:“可靠的”},{“stat.downloaded”:{" $ gt ": " 1000 "}}]})
由于在这样的一行语句中很难遵循查询逻辑,下面是相同的查询展开到几行并适当缩进:
物品。查找({" $and": [{" $or": [{"@deb. net . netArchitecture ": "i386"}, {"@deb。Architecture ": "amd64"}]}, {"@deb. Architecture "分发":"trusty"}, {"stat。下载":{"$gt":"1000"}}]})
狗粮很好吃。
在JFrog,我们以“吃自己的狗粮”为生。我们使用Artifactory继续开发Artifactory,我们通过Bintray分发Artifactory,现在我们很高兴在两个项目中使用AQL。我们使用它来实现清理策略,找出非常特定的工件,甚至根据不同的属性找到一个非常特定的模块子集,以便用一个相对简单的查询为Bintray组装一个构建,这将我们的脚本减少了80%。而这只是无限冰山的一角。AQL的设计非常灵活,可以满足您在可预见的未来可能想到的任何搜索需求。想想看,您可以用AQL查询的结果填充所有很酷的仪表板。
事实上,我们非常有信心AQL能够满足您的需求,因此我们将举办一场AQL挑战,挑战您为我们提供AQL无法处理的搜索场景。请继续关注,尽你最大的努力。
