I cannot find where to quote a field name that has a space in it, for example when doing
FILTER s._key = a.`Supplier Id`
The above, sql-style quote doesn't work, neither does array access. What's the correct way?
Figured it out now, I got bitten by SQL and forgot that equality comparison is made with == in AQL. Then the array access worked, so the way to use field names with spaces is this:
FILTER s._key == a['Supplier Id']
If the field is without spaces but has some special characters, it works to use backtick instead of array access:
FILTER s._key == a.`ÅterförsäljareId`
Edit: Another option is to use bind variables:
FILTER s._key == a.#field
// Passing this to the API as bind variables:
{
"field": "Supplier Id"
}
Related
How do we write conditions in arango, that includes for loops. I can elaborate the requirement below.
My requirement is if a particular attribute(array type) exists in the arango collection, i would read data from the collection(that requires a loop) or else, might do the following :
return null
return empty string ""
do nothing.
Is this possible to achieve in arango?
The helping methods could be -->
-- has(collectionname, attributename)
-- The ternary operator ?:
let attribute1 = has(doc,"attribute1") ?(
for name in doc.attribute1.names
filter name.language == "xyz"
return name.name
) : ""
But this dosent work. Seems like arango compiler first attempts to compile the for loop, finds nulls and reports error as below. Instead, it should have compiled "has" function first for the ternary operator being used.
collection or array expected as operand to FOR loop; you provided a value of type 'null' (while executing)
If there is a better way of doing it, would appreciate the advice!!
Thanks in advance!
Nilotpal
Fakhrany here from ArangoDB.
Regarding your question, this is a known limitation.
From https://www.arangodb.com/docs/3.8/aql/fundamentals-limitations.html:
The following other limitations are known for AQL queries:
Subqueries that are used inside expressions are pulled out of these
expressions and executed beforehand. That means that subqueries do not
participate in lazy evaluation of operands, for example in the ternary
operator. Also see evaluation of subqueries.
Also noted here for the ternary operator:
https://www.arangodb.com/docs/3.8/aql/operators.html#ternary-operator.
An answer to the question what to do may be to use a FILTER before enumerating over the attributes:
FOR doc IN collection
/* the following filter will only let those documents passed in which "attribute1.names" is an array */
FILTER IS_ARRAY(doc.attribute1.names)
FOR name IN doc.attribute1.names
FILTER name.language == "xyz"
RETURN name.name
Other solutions are also possible. Depends a bit on the use case.
Probably a silly question, but if in a collection I have documents which include attributes defined with spaces, example:
{
"attribute with spaces" : "blabla",
...
}
How can I query for finding it? I tried
for document in documents
filter document."attribute with spaces" == "blabla"
But of course I get a syntax error.
Attribute names that are reserved keywords or contain spaces or other characters not allowed in attribute names must be quoted with backticks:
FOR document IN documents
FILTER document.`attribute with spaces` == "blabla"
Alternatively you can use attribute access like this:
FOR document IN documents
FILTER document["attribute with spaces"] == "blabla"
This is also explained in the documentation: https://www.arangodb.com/docs/stable/aql/fundamentals-syntax.html#names
In the description of filtering records in Peewee, there are examples of two alternative syntaxes: using commas to separate multiple conditions, such as the following example,
Tweet.select().where(Tweet.user == user, Tweet.is_published == True)
and using bitwise operators. I cannot figure out (and cannot find a description of) the difference between using the comma syntax and using bitwise operators. What does the comma syntax actually do? From the (single) documented example of using a comma, it seems like it might be equivalent to using &, as in
Tweet.select().where( (Tweet.user == user) & (Tweet.is_published == True) )
Is that the case?
Yes, they are equivalent, as per the code:
def where(self, *expressions):
if self._where is not None:
expressions = (self._where,) + expressions
self._where = reduce(operator.and_, expressions)
This appears to be pretty basic but I am unable to find a suitable pipeline expression function to achieve this.
I have set an array variable VAR1 with the following value, which is an output from a SQL Lookup activity in an ADF pipeline:
[
{
"Code1": "1312312"
},
{
"Code1": "3524355"
}
]
Now, I need to convert this into a comma separated string so I can pass it to a SQL query in the next activity - something like:
"'1312312','3524355'"
I am unable to find an expression function to iterate over the array elements, nor convert an array to a string. The only pipeline expression functions I see are to convert string to array and not the other way around.
Am I missing something basic? How can this be achieved?
Use 'join' function present in 'collection' functions in 'Add dynamic content'. For example:
join(variables('ARRAY_VARIABLE'), ',')
I had this same issue and was not totally satisfied just using the join function because it keeps the keys from the json object. Also, using an iterator approach can work but is needlessly expensive and slow if you have a long list. Here was my approach, using join and replace:
replace(replace(join(variables('VAR1'), ','), '{"Code1":', ''), '}', ''))
This will give you exactly the output you are looking for.
I got it working using a ForEach loop activity to iterate over my array and use a Set Variable task with a concat expression function to create my comma separated string.
Wish they had an iterator function in the expression language itself, that would have made it much easier.
In case, you just have two elements in the array, then you can do something like:
#concat(variables('variable_name')[0].Code1, ',', variables('variable_name')[1].Code1)
I need to search mongodb collection for a specific pattern field. I tried using {$exists:true}; However, this gives results only if you provide exact field.
I tried using {$exists:true} for my field. But this does not give results if you give some pattern.
{
"field1":"value1",
"field2":"value2",
"field3":object
{/arjun1/pat1: 1,
/arjun2/pat2: 3,
/arjun3/pat3: 5
}
"field4":"value4",
}
From some field, I get the keys pat3 & field3. From this I would need to find out if the value /arjun3/pat3 exists in the document.
If I use {"field3./arjun3/pat3":{$exists:true}}, this would give me results. But the problem is I get only field3 and pat3 and I need to use some pattern matching like field3.*.pat3 and then use $expr or $exists; which I'm not exactly sure how to. Please help.
you could try something of this kind
db.arjun.find(
{"field3" : {
"$elemMatch" : { $and: [
{"arjun3.pat3" : {$exists:true}},
{"arjun3.pat3" : 5}
]
}}}
);
You can either go for regex (re module) for SQL like pattern matching, and compile your own custom wildcard. But if you don't want that then you can simple use the fnmatch module, it is a builtin library of python which allows wildcard matching for multiple characters (via*) or a single character (via ?).
import fnmatch
a = "hello"
print(fnmatch.fnmatch(a, "h*"))
OUTPUT:-
True