What will be the Query in my situation in Adobe CQ5 - jackrabbit

Root contains one folder, named pending of type sling:folder.
That have numbers of nodes of nt:unstructured type, having name of long value, that long value is very important for my code processing.
Now I want to get top 20 nodes(20 minimum node name , i.e., long value) data from this pending folder.
Can you tell me how can I write the JCR query for this situation ?
Edit No. 1
Repository repository = JcrUtils.getRepository("http://localhost:4502/crx/server");
Session session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
// Obtain the query manager for the session via the workspace ...
QueryManager queryManager = session.getWorkspace().getQueryManager();
// Create a query object ...
String expression = "SELECT * FROM [nt:base] AS s WHERE ISDESCENDANTNODE([/pending])";
Query query = queryManager.createQuery(expression, javax.jcr.query.Query.JCR_SQL2);
// Execute the query and get the results ...
QueryResult result = query.execute();
// Iterate over the nodes in the results ...
NodeIterator nodeIter = result.getNodes();
But it gives some order , different than the order present in root node. But that is not in sort form.
Edit No.2
Now I got the functionality of this function. And it working fine now. The thing that I got is order the node just above the destination node, that is mentioned in second parameter of this function.
But the nodes that is coming is of different names(a number). So how can I sort this using orderBefore. Because everytime we are not able to know the right location(destination Relative Path) where we have to put this node.

You probably don't need a query for this, if you have structure such as
/pending/1
/pending/2
...
/pending/999
you can just iterate over the nodes using the JCR Node's getNodes() method, which returns a NodeIterator.
A sling:orderedFolder node type for "pending" gives a predictable ordering of the child nodes.
In general, using the tree structure instead of queries is more efficient in JCR.
Note also that if you're using Jackrabbit having more than about 10'000 child nodes on the same parent can lead to performance issues.

Related

How to define nodes as arrival points and destination points

This is probably an easy question but I do not get it.
In my model I want to create orders based on real data, in this real data there is a start location , I set those as parameter value of the order agent from the database see pictures below:
Database anylogic
Parameters order agent
Now I want at the source block to let the order arrive at the departement, which is exactly the same name as the string parameter of the order, so I did this:
Source part
But it says, cannot convert from string to Inode, so my question is how do I type the syntax that he converts the string name to the node with exactly the same name, because the departement node also is called Departement1 etc.
Thanks in advance!
I would have liked to put this answer as a comment, as I'm still a relative beginner at AnyLogic and I'm sure there are more elegant approaches, but due to lack of reputation, here it it:
You can get the String value of the name of an INode object with INode.getName(), as documented here : https://anylogic.help/api/com/anylogic/engine/markup/INode.html#getName()
After which it would only be a matter of creating a creating a list that contains your nodes, creating a function that iterates through that list and fills out a Map with the name/node pair.
You can then use another function within your agent to assign the corresponding node to a variable inside your agent, and use that to dynamically define their arrival location.
Assuming you've created a Map of name col_nodeNameMatch, you'd then do something like :
for (INode n : col_nodes) {
if (n.getName().equals(departement)){
col_nodeNameMatch.put(departement, n);
break;
}
}
Followed by the following every time an agent needs to find its arrival node :
v_arrivalNode = col_nodeNameMatch.get(departement);
Thank you Stuart for the much more efficient suggestion of using a Map.

How to find a MoveTo destination filled by database?

I could need some help with a Anylogic Model.
Model (short): Manufacturing scenario with orders move in a individual route. The workplaces (WP) are dynamical created by simulation start. Their names, quantity and other parameters are stored in a database (excel Import). Also the orders are created according to an import. The Agent population "order" has a collection routing which contains the Workplaces it has to stop in the specific order.
Target: I want a moveTo block in main which finds the next destination of the agent order.
Problem and solution paths:
I set the destination Type to agent and in the Agent field I typed a function agent.getDestination(). This function is in order which returns the next entry of the collection WP destinationName = routing.get(i). With this I get a Datatype error (while run not compiling). I quess it's because the database does not save the entrys as WP Type but only String.
Is there a possiblity to create a collection with agents from an Excel?
After this I tried to use the same getDestination as String an so find via findFirst the WP matching the returned name and return it as WP. WP targetWP = findFirst(wps, w->w.name == destinationName);
Of corse wps (the population of Workplaces) couldn't be found.
How can I search the population?
Maybe with an Agentlink?
I think it is not that difficult but can't find an answer or a solution. As you can tell I'm a beginner... Hope the description is good an someone can help me or give me a hint :)
Thanks
Is there a possiblity to create a collection with agents from an Excel?
Not directly using the collection's properties and, as you've seen, you can't have database (DB) column types which are agent types.1
But this is relatively simple to do directly via Java code (and you can use the Insert Database Query wizard to construct the skeleton code for you).
After this I tried to use the same getDestination as String an so find via findFirst the WP matching the returned name and return it as WP
Yes, this is one approach. If your order details are in Excel/the database, they are presumably referring to workplaces via some String ID (which will be a parameter of the workplace agents you've created from a separate Excel worksheet/database table). You need to use the Java equals method to compare strings though, not == (which is for comparing numbers or whether two objects are the same object).
I want a moveTo block in main which finds the next destination of the agent order
So the general overall solution is
Create a population of Workplace agents (let's say called workplaces in Main) from the DB, each with a String parameter id or similar mapped from a DB column.
Create a population of Order agents (let's say called orders in Main) from the DB and then, in their on-startup action, set up their collection of workplace IDs (type ArrayList, element class String; let's say called workplaceIDsList) using data from another DB table.
Order probably also needs a working variable storing the next index in the list that it needs to go to (so let's say an int variable nextWorkplaceIndex which starts at 0).
Write a function in Main called getWorkplaceByID that has a single String argument id and returns a Workplace. This gets the workplace from the population that matches the ID; a one-line way similar to yours is findFirst(workplaces, w -> w.id.equals(id)).
The MoveTo block (which I presume is in Main) needs to move the Order to an agent defined by getWorkplaceByID(agent.workplaceIDsList.get(nextWorkplaceIndex++)). (The ++ bit increments the index after evaluating the expression so it is ready for the next workplace to go to.)
For populating the collection, you'd have two tables, something like the below (assuming using strings as IDs for workplaces and orders):
orders table: columns for parameters of your orders (including some String id column) other than the workplace-list. (Create one Order agent per row.)
order_workplaces table: columns order_id, sequence_num and workplace_id (so with multiple rows specifying the sequence of workplace IDs for an order ID).
In the On startup action of Order, set up the skeleton query code via the Insert Database Query wizard as below (where we want to loop through all rows for this order's ID and do something --- we'll change the skeleton code to add entries to the collection instead of just printing stuff via traceln like the skeleton code does).
Then we edit the skeleton code to look like the below. (Note we add an orderBy clause to the initial query so we ensure we get the rows in ascending sequence number order.)
List<Tuple> rows = selectFrom(order_workplaces)
.where(order_workplaces.order_id.eq(id))
.orderBy(order_workplaces.sequence_num.asc())
.list();
for (Tuple row : rows) {
workplaceIDsList.add(row.get(order_workplaces.workplace_id));
}
1 The AnyLogic database is a normal relational database --- HSQLDB in fact --- and databases only understand their own specific data types like VARCHAR, with AnyLogic and the libraries it uses translating these to Java types like String. In the user interface, AnyLogic makes it look like you set the column types as int, String, etc. but these are really the Java types that the columns' contents will ultimately be translated into.
AnyLogic does support columns which have option list types (and the special Code type column for columns containing executable Java code) but these are special cases using special logic under the covers to translate the column data (which is ultimately still a string of characters) into the appropriate option list instance or (for Code columns) into compiled-on-the-fly-and-then-executed Java).
Welcome to Stack Overflow :) To create a Population via Excel Import you have to create a method and call Code like this. You also need an empty Population.
int n = excelFile.getLastRowNum(YOUR_SHEET_NAME);
for(int i = FIRST_ROW; i <= n; i++){
String name = excelFile.getCellStringValue(YOUR_SHEET_NAME, i, 1);
double SEC_PARAMETER_TO_READ= excelFile.getCellNumericValue(YOUR_SHEET_NAME, i, 2);
WP workplace = add_wps(name, SEC_PARAMETER_TO_READ);
}
Now if you want to get a workplace by name, you have to create a method similar to your try.
Functionbody:
WP workplaceToFind = wps.findFirst(w -> w.name.equals(destinationName));
if(workplaceToFind != null){
//do what ever you want
}

Arangodb update properties depend on edge type

I am trying to use AQL to update the whole node collection , named Nodes, depend on the type of edges they have
.
Requirement:
Basically, if 2 entity in Nodes has relation type= "Same", they would be updated with unique groupid properties (same for more than 2)
This would only run one time in the beginning (to populate groupid)
My concept approach:
Use AQL
For each entity inside Node, query out all connectable nodes with type=SAME
Generate an groupid and Update all of them
Write to an lookup object those id
For next entity, do a lookup, skip the entity if their id is there.
What I tried
FOR v,e,p
In 1..10
ANY v
EntityRelationTest
OPTIONS {uniqueVertices:"global",bfs:true}
FILTER p.edges[*].relationType[0]== "EQUALS"
UPDATE v WITH { typeName2:"test1"} IN EntityTest
return NEW
But I am quite new to arangodb AQL, is something like above possible?
In the end, what I use is a customize traversal object running directly inside Foxx in order to get the best of both world: performance and correctness. It seemed that we cannot do the above with only AQL

OrientDB - find "orphaned" binary records

I have some images stored in the default cluster in my OrientDB database. I stored them by implementing the code given by the documentation in the case of the use of multiple ORecordByte (for large content): http://orientdb.com/docs/2.1/Binary-Data.html
So, I have two types of object in my default cluster. Binary datas and ODocument whose field 'data' lists to the different record of binary datas.
Some of the ODocument records' RID are used in some other classes. But, the other records are orphanized and I would like to be able to retrieve them.
My idea was to use
select from cluster:default where #rid not in (select myField from MyClass)
But the problem is that I retrieve the other binary datas and I just want the record with the field 'data'.
In addition, I prefer to have a prettier request because I don't think the "not in" clause is really something that should be encouraged. Is there something like a JOIN which return records that are not joined to anything?
Can you help me please?
To resolve my problem, I did like that. However, I don't know if it is the right way (the more optimized one) to do it:
I used the following SQL request:
SELECT rid FROM (FIND REFERENCES (SELECT FROM CLUSTER:default)) WHERE referredBy = []
In Java, I execute it with the use of the couple OCommandSQL/OCommandRequest and I retrieve an OrientDynaElementIterable. I just iterate on this last one to retrieve an OrientVertex, contained in another OrientVertex, from where I retrieve the RID of the orpan.
Now, here is some code if it can help someone, assuming that you have an OrientGraphNoTx or an OrientGraph for the 'graph' variable :)
String cmd = "SELECT rid FROM (FIND REFERENCES (SELECT FROM CLUSTER:default)) WHERE referredBy = []";
List<String> orphanedRid = new ArrayList<String>();
OCommandRequest request = graph.command(new OCommandSQL(cmd));
OrientDynaElementIterable objects = request.execute();
Iterator<Object> iterator = objects.iterator();
while (iterator.hasNext()) {
OrientVertex obj = (OrientVertex) iterator.next();
OrientVertex orphan = obj.getProperty("rid");
orphanedRid.add(orphan.getIdentity().toString());
}

CakePHP 3 Tree Behavior - numeric value out of range on save, delete, or move functions

I'm working with CakePHP 3.0's Tree Behavior and get an interesting issue when I'm trying to delete nodes. There are two types of nodes under a team - internal and external. The internal nodes are teams in the tree structure beneath me that I have complete access over; the external nodes are teams underneath me that have their own teams they've fleshed out, and as such I don't have permission to alter them (I only have permission to remove the entire top-level owner, but not modify the actual structure of their team).
So let's say I have a structure like this:
x
/ | \
* o o x o = internal
/ x = external
o * = node I'm trying to delete
/ \
o x
I have a delete function I've written to delete team nodes. If I delete the node with an asterisk by it, I expect it to delete every node underneath it. When I hit an external node (the x at the bottom) it should instead change the parent_id to null, since I don't have permission to delete somebody else's external team.
My logic is recursive and basically calls itself for every child under with logic similar to this:
if ($team->external === 1) {
$team->parent_id = null;
$this->save($team);
} else {
$this->delete($team);
}
I won't write out the whole function for the sake of brevity, but this functionality continues until all nodes have been deleted. Unfortunately, I get this error when I try and run the function:
"SQLSTATE[22003]: Numeric value out of range: 1690 BIGINT UNSIGNED value is out of range in '((`my_application`.`teams`.`lft` + 1182) * -(1))'"
So this looks like an issue with the lft or rght values (perhaps) and I'm confused as to why it's getting multiplied by a -1...either way, I'm not exactly sure what the case is here.
I get the same issue when I'm running other functions, like a move command. If I want to move a user underneath a different node, I might do something like this in my controller:
$team->parent_id = $this->request->data['id']; // let's say it's '21'
$this->Teams->save($team);
The same issue happens here where I get a 'numeric value out of range' issue. I've run $this->recover(); on the table a few times just to make sure the table's lft and rght values were all correct and the issue still occurs.
Does anybody have any idea?
Well, this is an implementation gotcha for the tree behavior in its current form. In order to speed up some operations, it relies on being able to set negative values to some of the nodes. Therefore, having an UNSIGNED column will not work correctly.
The easiest solution right now is to remove the UNSIGNED flag in the lft and rght columns.

Resources