Gremlin optional as empty - gremlin

Could you please help me to understand whether there is any option where we can skip the optional in the gremlin,
the scenario is, we are traversing through a graph and has an optional statement
depending on a query parameter in the request, I will be having a traverse path for optional, if not, there is no path for the optional
for example,
if query_parameter:
path=has('labeltest').inE().outV()
g.V('test').optional(path)
as optional path is for the query_parameter available condition, this is failing and returning no result if query parameter not available. We don't prefer to repeat the code on the g.v() by an if and else condition. Any thoughts to tell the optional to not do anything or dummy options to return the previous path. Appreciate your thoughts as I am new to this, thank you in advance
Regards
Hari

In the case where you want nothing to happen you could just set your path variable to be identity(). The effect would be as follows:
gremlin> g.V('3').optional(identity())
==>v[3]
Specifically, in Python you can do this:
>>> p=__.identity()
>>> g.V('3').optional(p).next()
v[3]

If you are doing this from python using the Gremlin Language Variant (GLV) then you can only add the optional portion of the query when needed. GLV's are lazily evaluated so you can conditionally construct them in code. They will only be executed when you add a terminal step (e.g. toList()). This means that you can build your traversal like this:
t=g.V('test')
if query_parameter:
t=t.has('labeltest').inE().outV()
res=t.toList()
With this code, the optional path portion of the traversal will only be executed when query_parameter is True, else it will just return the test vertex.

Related

how to write query where the input file is passed from the command line (Saxon)

I'm very new to this.
I have a query and an xml file.
I can write a query over that specific file
for $x in doc("file:///C:/Users/Foo/IdeaProjects/XQuery/src/books.xml")/bookstore/book
where $x/price>30
order by $x/title
return $x/title
I have a basic xml file, with books in it, works nicely in intellij.
but if I wanted to run this query against some file defined on the command line, then how do I do it?
the command line for running the above is (as much for other peoples reference)
java -cp C:\Users\Foo\.IdeaIC2019.2\config\plugins\xquery-intellij-plugin\lib\Saxon-HE-9.9.1-7.jar net.sf.saxon.Query -t -q:"C:\Users\Foo\IdeaProjects\XQuery\src\w3schools.com.xqy"
and that also works nicely.
the saxon documentation
https://www.saxonica.com/html/documentation/using-xquery/commandline.html
implies that I can specify an input file, using "-d"
and "The document node of the document is made available to the query as the context item"
but this doesnt really make any sense to my 1 day old XQuery skills.
how do I specify the document is sent from the command line in the query? what is the context item? and how do I reference it?
(I can do a bit of XSLT 1.0, so I understand the notion of a context).
I think the option is named -s (for source) so you can use -s:books.xml and inside your XQuery main expression any path is evaluated with that document as the context item so you can just use e.g.
for $x in /bookstore/book
where $x/price>30
order by $x/title
return $x/title
and the answer is to drop the doc() function
for $x in bookstore/book
i.e. the same notion as xslt.

Gremlin Java replace old vertex properties with new property

I am trying to use gremlin java to replace some vertex's property like this:
graph.V(1).properties().drop().property("foo", "bar").iterate()
However, this only remove property but doesn't add new property.
I think iterate should probably be immediately after drop, but I am connecting to remote graph db so I wish to reduce query count.
Hope there is some way to achieve this:
graph.V(1).properties().drop().property("foo", "bar")
.V(2).properties().drop().property("foo", "bar").....iterate()
Yes, you can definitely do that, check out the live example: https://gremlify.com/27
You can select the vertex and see it's properties, or run g.V().valueMap(true) and afterwards:
g.V().sideEffect(properties ().drop()).property ("foo", "boo");
To see the new properties applied to it.
(For simplicity, I assumed a single vertex on the graph but this applies for any vertex).
The answer by #gremlify is correct. And alternatively you can use .union() command also.
g.V().union(
properties().drop(),
property('foo', 'boo')
);

Neo4j: How to use APOC apoc.algo.cover procedure?

Hi,
I try to use the "cover" function from APOC like this :
WITH ["f1,"f2",...] as list1
MATCH (n:Frag)
WHERE n.frag in list1
WITH COLLECT(ID(n)) as nodeIds
CALL apoc.algo.cover(nodeIds)
YIELD rel
RETURN rel
It works but it is very slow the first time. If I do it once again, it becomes muck quicker! What does that mean?
Probably your issue is not related to apoc.algo.cover usage, but to the WHERE part of your query. You can try a performance improvement adding an index in the Frag.frag property.
CREATE INDEX ON :Frag(frag)
After creating the index run your query again. Note that the index is not immediately available, but will be created in the background.

Xquery optimization

I have this xquery as follows:
declare variable $i := doc()/some-element/modifier[empty(modifier-value)];
$i[1]/../..;
I need to run this query on Marklogic's Qconsole where we have 721170811 records. Since that is huge number of record, I am getting timeout error. Is there any way I can optimize this query to get the result?
P.S. I cannot request amdin to increase the timeout time.
Try creating an element range index (or a path range index if the target element is not unique) and using a cts:values() lexicon lookup.
That way, the request can read the values from the range index instead of having to read each document.
See:
http://docs.marklogic.com/guide/search-dev/lexicon
You could use xdmp:spawn, create a library when you will make the query, get the documents, iterate the result collecting 1000 documents per iteration and call another xdmp:spawn to process the information from that dataset, I would suggest summarize the result to return only the information you will need to don't crash the browser, at the end should look something like this:
xdmp:spawn("process.xqy")
into the library process.xqy
function local:start-process(){
let $docs := (....)
let $temp := for $x in $docs[$start to $end]
return local:process-dataset($temp) (: Could use spawn here too if you want :)
return xdmp:spawn("collect.xqy",$temp)
}
local:start-process()
compact-data function should create a file or a set of files with your data, this way the server will run all the process and in some minutes you will be available to see your data without problems.
You don't want to run something like doc() or xdmp:directory - just returns a result set that will kill you every time. You need to lower your result set by a lot.
A few thoughts:
You want to have as much done in MarkLogic's d-node, and the least work done in the e-node as possible. This is a way over-generalization, but for the most part I look at it like d-node stuff is data, indexes, lexicon work, etc. e-node stuff handles xQuery and such. So, in your example, you're definitely working out the e-node more than you need to.
You're going to want to use cts:search, as it uses indexes, not xPath to resolve your query. So, something like this:
declare variable $i := cts:search(fn:collection(),
cts:element-query(xs:QName("some-element"),
cts:element-value-query(xs:QName("modifier"), "", "exact")
)
)[1];
This will return document-node's, which it looks like what you were wanting with the $i[1]/../... This searches the xPath some-element for a modifier that is empty.
Please create element range index and attribute range index and use cts:search if you are familiar with marklogic it will be easy for you to write the query.

Lotus Notes #formula language: Order of Actions wrong?

I have defined an action with the following two commands:
#Prompt([...]; "1");
#Command([ToolsRunMacro];"(AGENT)");
#Prompt([...]; "2");
#If(#GetProfileField("PrivateProfile";"LENGTH";#UserName))>0;#PostedCommand([Compose];"FORM");"");
#Prompt([...]; "3");
But with the #Prompt commands I found out, that first of all each of the #Promptmessages (1-3) are displayed and after that the AGENT runs. But as the AGENT manipulates the LENGTHfield, the #IF statement compares an 'obsolete' value.
Maybe each statement is executed at once? If yes: how can I prevent the agent from this behavior?
I would appreciate any help!
The [ToolsRunMacro] command will always run after all #Functions have executed first. There is no way to change this.
You can get a list of what commands will execute straight away vs after other functions that execute at the end, in the infocenter documentation.
http://publib.boulder.ibm.com/infocenter/domhelp/v8r0/topic/com.ibm.designer.domino.main.doc/H_COMMAND.html
Also something to be aware on your code is that Profile documents are cached. So you might not in all cases see any changes made to the document straight away.

Resources