In Google DataStore GQL, how can I group the WHERE terms? - google-cloud-datastore

I need to group terms in the WHERE clause. For example,
WHERE (param1='foo1' OR param1='foo2') AND (param2='bar1' OR param2='bar2')
But it's giving me a syntax error saying that the parentheses are "unexpected". The actual error is:
GQL query error: Encountered "(" at line 1, column 29. Was expecting one of: "false", "null", "true", <INTEGER>, <DOUBLE>, <SINGLE_QUOTE_STRING>, <DOUBLE_QUOTE_STRING>, <UNQUOTED_NAME>, <QUOTED_NAME>, <NAME_BINDING_SITE>, <POSITION_BINDING_SITE>
So, is there any way for me to run that query?

I believe the problem you're facing comes from the OR operator - GQL doesn't have one, so the conditions you have in the paranthesis are syntactically incorrect.
From the WHERE row in the Clauses table (emphasis mine):
Limits the result set to those entities that meet one or more
conditions. Each condition compares a property of the entity with a
value using a comparison operator. If multiple conditions are combined
with the AND keyword, then an entity must meet all of the
conditions to be returned by the query. GQL does not have an OR
operator.

Related

Find the documents which have element in proper "dateTime" format

I am trying the following query in marklogic-9:
cts:element-value-match(xs:QName("cd:modificationDate"), "[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01].000Z", ("type=dateTime","timezone=TZ"))
to achieve this, but this gives me the following error:
[1.0-ml] XDMP-ARG: cts:element-value-match(xs:QName("cd:modificationDate"), "[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01].000Z", ("type=dateTime", "timezone=TZ")) -- arg2 is invalid
What i want to do is to find out all those documents which conforms to this specific pattern of dateTime. We have a date-range index on this element - modificationDate.
How best can we do this using marklogic and xquery api.
cts:element-value-match is really only useful on string range indexes and even there it only takes simple wildcards (* and ?), not general regular expressions or date formats.
If your range index is a dateTime range index, then every value must conform to the proper xs:dateTime format, so this query would tell you nothing.
This will give you a list of all the URIs where you have a valid dateTime in that element:
cts:uris("", (),
cts:element-range-query(xs:QName("modificationDate"), ">", xs:dateTime("0001-01-01T00:00:00"))
)

Xquery Where clause not working when using nested query

Good Day,
I'm new to xquery.
I'm trying to execute xquery with a where clause that returns the values greater than a value returned from a nested query as show below. It runs but returns values that are not greater than the returned value
If I use the where clause directly with the value it works fine. I'm using BaseX to execute my query. Appreciate any feedback, I believe the parser may be reading my subquery wrong.
for $y in doc("url.xml")/taxi_stations/stand
where $y/taxis>=
(
for $x in doc("url.xml")/taxi_stations/stand
where $x/name="Jacksonville"
return data($x/taxis)
)
return ($y/taxis,$y/name)
What is the value of $taxis? It's possible your comparisons are happening on strings, not numbers.
In your nested return, you call data() on $x/taxis - assuming that correctly returns a number value, then $y/taxis in your outer where clause should probably also be wrapped in data().
However, if there is no schema on your document, then data() will simply return a string. In that case you should convert your taxis element to a number using fn:number() or directly casting it like $y/taxis/xs:integer(.).

Marklogic collate sequence in XQuery

Is there a way to modify the elements a sequence so only collated versions of the items are returned?
let $currencies := ('dollar', 'Dollar', 'dollar ')
return fn:collated-only($currencies, "http://marklogic.com/collation/en/S1/T00BB/AS")
=> ('dollar', 'dollar', 'dollar')
The values that are stored in the range index (that feeds the facets) are literally the first value that was encountered that compared equal to the others. (Because, the collation says you don't care...)
You can get a long way by calling
fn:replace(fn:lower-case(xdmp:diacritic-less(fn:normalize-unicode($str,"NFKC"))),"\p{P}","")
This won't be exactly the same in that it overfolds some things and underfolds others, but it may be good for your purposes.
Is this the expected output? There is no fn:collated-only function, so I'm assuming you're asking how to write such a function or whether there is such a function.
The thing is, there isn't a mapping from one string to another in collation comparisons, there is only a comparison algorithm (the Unicode Collation Algorithm) so there really is no canonical kind of string to return to you, and therefore no API to do so.
Stepping back, what is the problem you are actually trying to solve? By the rules of that collation, "dollar" and "Dollar" are equivalent, and by using it you declare you don't care which form you use, so you could use either one.
If these values are in XML elements and you have a range index using http://marklogic.com/collation/en/S1/T00BB/AS, you can do something like this:
let $ref := cts:element-reference(xs:QName("currency"), "collation=http://marklogic.com/collation/en/S1/T00BB/AS")
for $curr in cts:values($ref, (), "frequency-order")
return $curr || ": " || cts:frequency($curr)
This will produce results like:
"dollar: 15",
"euro: 12"
... and so on. The collation will disregard the differences among your sample inputs. These results could be formatted however you want. Is that what you're looking to do?

Xquery version of "NOT IN" clause not working as expected

I have an xml file which can be downloaded in the following link:
http://expirebox.com/download/483d465091802df68da10feddc1ec98c.html
I am trying to select all those movies without the styles of "live action" and "camp" in my movies.xml. To achieve this I am using the following query
for $movie in db:open("movies","movies.xml")/movies/movie
where $movie/styles/style!=("noir","anthology")
return $movie
However, all nodes in movies are getting selected. What is going wrong in my query?
Some experts are pointing out the inability of the standard not equal operator not working in this case due to the semantics of XQuery involved. However, my intention is to find a corresponding query of an SQL feature and not just understand the semantics.
!= uses set comparison logic.
For values that are not in that sequence, such as "foo", the expression "foo" != ("noir", "anthology") returns true However, the expression "noir" != ("noir", "anthology") would also return true. This is because "noir" does not equal one of the items in the sequence, "anthology", even though it also equals one of the items in the sequence as well. The expression "noir" = ("noir", "anthology") returns true because "noir" is equal to one of the items in the sequence, "noir".
Refer to the specification:
https://www.w3.org/TR/1999/REC-xpath-19991116/#booleans
NOTE: If $x is bound to a node-set, then $x="foo" does not mean the same as not($x!="foo"): the former is true if and only if some node in $x has the string-value foo; the latter is true if and only if all nodes in $x have the string-value foo.
Use:
where not($movie/styles/style=("noir","anthology"))
or:
where $movie/styles/style[not(.=("noir","anthology"))]

missing operand before '<' operator in datatable select

In the data table there is column that is composite date that has the value of the date with some conditions i want to filter the data table.
The expression that i am making is giving me error .
Expression
scaleID=8207 and CompositeDate >= '5/1/2009 6:01:23 PM' And CompositeDate =< '5/31/2009 6:01:23 PM'
what is that i am missing here if it cannot be done in this way can we use LINQ for this if yes can any one provide me with the syntax.
You're using =< when I suspect you mean <=.
The docs for the expression syntax include <=, but I can't see anything to suggest that =< is valid.
Personally I would try to avoid magic strings as far as possible and use LINQ instead (even within datatables) but that's a different matter.

Resources