简体   繁体   English

ArangoDB AQL:查找顺序数据中的差距

[英]ArangoDB AQL: Find Gaps In Sequential Data

I've been given data to build an application that has sequential data in the form of part numbers of products: "000000", "000001", "000002", "000010", "000011"... .我已经获得了数据来构建一个应用程序,该应用程序具有产品部件号形式的顺序数据: "000000", "000001", "000002", "000010", "000011"... The previous application was an old MS Access database that didn't have any gap filling features in the part number generator, hence the gap between "000002" and "000010" (Yes, they are also strings, but I can work with that...).以前的应用程序是一个旧的 MS Access 数据库,在零件编号生成器中没有任何间隙填充功能,因此"000002""000010"之间的间隙(是的,它们也是字符串,但我可以使用它。 ..)。

We could continue to increment based on the last value and ignore the gaps, however, in an attempt to use all numbers available to us with our naming scheme, we'd like to be able to fill the gaps.我们可以继续基于最后一个值递增并忽略空白,但是,为了尝试将所有可用的数字用于我们的命名方案,我们希望能够填补空白。 Our naming scheme describes the "product family" with the first two digits such that: [00]0000 would be a different family from [02]0000 .我们的命名方案使用前两位数字描述“产品系列”,这样: [00]0000将是与[02]0000不同的系列。

I can find the starting and ending values using something like:我可以使用以下方法找到起始值和结束值:

let query = `
  LET first = (
    MIN(
      FOR part in part_search
        SEARCH STARTS_WITH(part.PartNumber, @family)
        RETURN part.PartNumber
    )
  )
  LET last = (
    MAX(
      FOR part in part_search
        SEARCH STARTS_WITH(part.PartNumber, @family)
        RETURN part.PartNumber
    )
  )
  RETURN { first, last }
`

The above example returns: {first: "000000", last: "000915"}上面的例子返回: {first: "000000", last: "000915"}

Using ArangoDB and AQL, how could I go about finding these gaps?使用 ArangoDB 和 AQL,我怎么能找到这些差距? I've found some SQL examples but I feel the features of AQL are a bit more limiting.我发现了一些 SQL 示例,但我觉得 AQL 的功能有点限制。

Thanks in advance!提前致谢!

To start with, I think your best bet for getting min/max values is using aggregates:首先,我认为获得最小值/最大值的最佳选择是使用聚合:

FOR part in part_search
    SEARCH STARTS_WITH(part.PartNumber, @family)
    COLLECT x = 1
    AGGREGATE first = MIN(part.PartNumber), last = MAX(part.PartNumber)
    RETURN {
        first: first,
        last: last
    }

But that won't really help when trying to find gaps.但这在尝试寻找差距时并没有真正的帮助。 And you're right - SQL has several logical constructs that could help (like using variables and cursor iteration), but even that would be a pattern I would discourage.你是对的 - SQL 有几个可以提供帮助的逻辑结构(比如使用变量和 cursor 迭代),但即使这样也是我不鼓励的模式。

The better path might be to do a "brute force" approach - compare a table containing your existing numbers with a table of all numbers, using a native method like JOIN to find the difference.更好的方法可能是使用“蛮力”方法 - 将包含现有数字的表与所有数字的表进行比较,使用像JOIN这样的本地方法来找出差异。 Here's how you might do that in AQL:以下是在 AQL 中执行此操作的方法:

LET allNumbers = 0..9999
LET existingParts = (
    FOR part in part_search
        SEARCH STARTS_WITH(part.PartNumber, @family)
        LET childId = RIGHT(part.PartNumber, 4)
        RETURN TO_NUMBER(childId)
)
RETURN MINUS(allNumbers, existingParts)

The x..y construct creates a sequence (an array of numbers), which we use as the full set of possible numbers. x..y构造创建了一个序列(一个数字数组),我们将其用作完整的可能数字集。 Then, we want to return only the "non-family" part of the ID (I'm calling it "child"), which needs to be numeric to compare with the previous set.然后,我们只想返回 ID 的“非家庭”部分(我称之为“孩子”),它需要是数字才能与前一组进行比较。 Then, we use MINUS to remove elements of existingParts from the allNumbers list.然后,我们使用MINUSallNumbers列表中删除existingParts的元素。

One thing to note, that query would return only the "child" portion of the part number, so you would have to join it back to the family number later.需要注意的一点是,该查询将仅返回零件编号的“子”部分,因此您必须稍后将其加入到系列编号中。 Alternatively, you could also skip string-splitting, and get "fancy" with your list creation:或者,您也可以跳过字符串拆分,并在创建列表时获得“花哨”:

LET allNumbers = TO_NUMBER(CONCAT(@family, '0000'))..TO_NUMBER(CONCAT(@family, '9999'))
LET existingParts = (
    FOR part in part_search
        SEARCH STARTS_WITH(part.PartNumber, @family)
        RETURN TO_NUMBER(part.PartNumber)
)
RETURN MINUS(allNumbers, existingParts)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM