Apologies, but providing an application that includes a homebrew introspection framework does make this a lot more complex. I don’t have time to dive into all of the moving pieces.
Since you’re asking about TimeAdd
, I think it’s useful to isolate that use case to determine whether the problem is FQL itself or elsewhere. Based on what I can see in your repo, it looks like the FQL-only setup is equivalent to:
> CreateCollection({ name: "CrawlingQuery"})
{
ref: Collection("CrawlingQuery"),
ts: 1666654819730000,
history_days: 30,
name: 'CrawlingQuery'
}
> Create(Collection("CrawlingQuery"), {
data: {
keyword: "A",
schedule: { amount: 24, unit: "hours" }
}
})
{
ref: Ref(Collection("CrawlingQuery"), "346445339134263808"),
ts: 1666654871970000,
data: { keyword: 'A', schedule: { amount: 24, unit: 'hours' } }
}
> Create(Collection("CrawlingQuery"), {
data: {
keyword: "B",
schedule: { amount: 24, unit: "days" }
}
})
{
ref: Ref(Collection("CrawlingQuery"), "346445363990757888"),
ts: 1666654895690000,
data: { keyword: 'B', schedule: { amount: 24, unit: 'days' } }
}
> Create(Collection("CrawlingQuery"), {
data: {
keyword: "C",
schedule: { amount: 24, unit: "minutes" },
executions: [Now()]
}
})
{
ref: Ref(Collection("CrawlingQuery"), "346445483271520768"),
ts: 1666655009460000,
data: {
keyword: 'C',
schedule: { amount: 24, unit: 'minutes' },
executions: [ Time("2022-10-24T23:43:29.420Z") ]
}
}
> CreateIndex({
name: "by_expiry",
source: {
collection: Collection("CrawlingQuery"),
fields: {
expiry: Query(
Lambda(
"document",
TimeAdd(
Select(["data", "executions", 0], Var("document"), Epoch(0, 'second')),
Select(["data", "schedule", "amount"], Var("document")),
Select(["data", "schedule", "unit"], Var("document")),
)
)
),
},
},
values: [
{ binding: 'expiry' },
{ field: ["ref"] },
]
})
{
ref: Index("by_expiry"),
ts: 1666655153850000,
active: true,
serialized: true,
name: 'by_expiry',
source: {
collection: Collection("CrawlingQuery"),
fields: {
expiry: Query(Lambda("document", TimeAdd(Select(["data", "executions", 0], Var("document"), Epoch(0, "second")), Select(["data", "schedule", "amount"], Var("document")), Select(["data", "schedule", "unit"], Var("document")))))
}
},
values: [ { binding: 'expiry' }, { field: [ 'ref' ] } ],
partitions: 8
}
> CreateFunction({
name: "nextCrawlingQueries",
body: Query(
Lambda(
['indexName', 'size', 'afterCursor', 'beforeCursor'],
Map(
Paginate(
Filter(
Match(Index(Var('indexName'))),
Lambda(['expiry', '_'], LTE(Var('expiry'), Now()))
),
),
Lambda(['_', 'ref'], Get(Var('ref')))
),
),
)
})
{
ref: Function("nextCrawlingQueries"),
ts: 1666656373770000,
name: 'nextCrawlingQueries',
body: Query(Lambda(["indexName", "size", "afterCursor", "beforeCursor"], Map(Paginate(Filter(Match(Index(Var("indexName"))), Lambda(["expiry", "_"], LTE(Var("expiry"), Now())))), Lambda(["_", "ref"], Get(Var("ref"))))))
}
Does that look about right? If so, now we can diagnose.
Since the by_expiry
index has no terms
defined, this query should demonstrate whether the binding is working as expected:
> Paginate(Match(Index("by_expiry")))
{
data: [
[
Time("1970-01-02T00:00:00Z"),
Ref(Collection("CrawlingQuery"), "346445339134263808")
],
[
Time("1970-01-25T00:00:00Z"),
Ref(Collection("CrawlingQuery"), "346445363990757888")
],
[
Time("2022-10-25T00:07:29.420Z"),
Ref(Collection("CrawlingQuery"), "346445483271520768")
]
]
}
That result certainly makes it look like TimeAdd
is behaving as expected. Only the C
document has an executions array, so it is the only document that does not have a Unix epoch-based time value in the result.
And when I call the UDF:
> Call(Function("nextCrawlingQueries"), "by_expiry", 50, "after", "before")
{
data: [
{
ref: Ref(Collection("CrawlingQuery"), "346445339134263808"),
ts: 1666654871970000,
data: { keyword: 'A', schedule: { amount: 24, unit: 'hours' } }
},
{
ref: Ref(Collection("CrawlingQuery"), "346445363990757888"),
ts: 1666654895690000,
data: { keyword: 'B', schedule: { amount: 24, unit: 'days' } }
}
]
}
The C
document doesn’t appear in this result because its executions
timestamp is 24 minutes in the future, and not less than Now()
.
All this means is that the FQL portions of your application do appear to be working as expected.
From here, I’m not sure where the problem lies. My expertise is not with GraphQL, or TypeScript. So I’m not sure whether there’s an unexpected interaction with the GraphQL API, a problem with your schema definition, or something in your application that is the problem.
Currently, I see no reason that the non-hardcoded values should return an empty result compared to the hardcoded values, because (as demonstrated), the non-hardcoded queries work well.