0
votes

I'm working on building a complex searching query which allows the user to search the database on multiple values simultaneously. The form submits all of the fields (whether holding data or not) which looks something like (simplified):

{
  "PartNumber": "000000",
  "Requestor": "",
  "Assigned" true
}

In the above case, I am searching the database where the PartNumber is equal to 000000 and Assigned is true. Since Requestor is empty, I want to ignore that.

I found that you can build AQL Fragments but I can't seem to get them to work. I've tried:

const query = `
  FOR part in ${parts}
    ${aql.literal(PartNumber ? `FILTER part.PartNumber == ${PartNumber}` : "")}
    ${aql.literal(Requestor ? `FILTER part.Requestor == ${Requestor}` : "")}
    ${aql.literal(Assigned ? `FILTER part.Assigned == ${Assigned}` : "")}
    RETURN part
`

const results = db._query(query)

But no luck, I am getting a strange error: ArangoError: AQL: syntax error, unexpected :, expecting ] near ': 105600]

I've been banging my head on the wall over this, is there something I am missing?

Thanks in advance!


EDIT - Additional Testing

Using this simple query:

const query = `
  FOR part in ${parts}
    ${aql.literal(PartNumber ? `FILTER part.PartNumber == "000000"` : "")}
    RETURN part
`

I return JUST the query before it gets to the database and it is showing: "\"\\nFOR part in [ArangoCollection: 105600]\\n[object Object]\\nRETURN part\\n\""

You can see that the aql.literal() is returning [object Object] for my conditional. Outputting this as a string, it's returning {}. The variable PartNumber is defined so the conditional is truthy.


EDIT - Found A Solution

Is this the proper way to conditionally use multiple fields?

let query = `
  FOR part IN parts
    ${PartNumber ? `FILTER CONTAINS(part.PartNumber, "${PartNumber}")` : ""}
    ${Requestor ? `FILTER CONTAINS(part.Requestor, "${Requestor}")` : ""}
    RETURN part
`
const results = db._query(query)
res.send(results)
1
What does query look like at the time you send it to the DB?mpoeter
@mpoeter Good test, I found that each of the aql.literal() conditionals are returning [object Object]. When examining further, it is returning simply: {}. I'll put more details in an edit above.Justin

1 Answers

0
votes

aql.literal returns an object that is understood by the query template tag, but that means that you actually need to use the query template tag - i.e. query`...` instead of `...`:

const query = query`
  FOR part in ${parts}
    ${aql.literal(PartNumber ? `FILTER part.PartNumber == ${PartNumber}` : "")}
    ${aql.literal(Requestor ? `FILTER part.Requestor == ${Requestor}` : "")}
    ${aql.literal(Assigned ? `FILTER part.Assigned == ${Assigned}` : "")}
    RETURN part
`