Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unstable neo4j update #388

Closed
wants to merge 11 commits into from
Closed

Unstable neo4j update #388

wants to merge 11 commits into from

Conversation

LaraMerdol
Copy link
Collaborator

@LaraMerdol LaraMerdol commented Oct 9, 2023

I have made changes to the visual application in response to the issues mentioned in #387. The modifications involve using Neo4j version 5.10. Here are the details of the changes made:

  1. The APOC procedure 'apoc.cypher.runTimeboxed' has been deprecated in Neo4j 4 and later versions. Since there is no direct replacement with a built-in timeout parameter in the newer versions of APOC, I have used 'apoc.cypher.run' and implemented a timeout mechanism inside the 'neo4j-db.service.ts'.
  2. The function ID() is deprecated and it is recommended to use elementID() instead. To solve this problem, I have used elementId instead of id. The elementID is a string type and is structured as "4:c0a65d96-4993-4b0c-b036-e7ebd9174905:0". However, this type of id is not a proper selector id because it is also used as a CSS selector. To overcome this problem, I converted the colon (:) to an underscore (_) to create a valid CSS selector character sequence. For example, "4:c0a65d96-4993-4b0c-b036-e7ebd9174905:0" becomes "n4_c0a65d96-4993-4b0c-b036-e7ebd9174905_0".
  3. The default minimum password length is 8 characters, which is a requirement introduced in Neo4j 5.3.

For testing on your local environment, you can use the new Neo4j 5.10 database working on the ivis server port:3001. The credentials are username: neo4j and password: 12345678. You should change the environment.ts accordingly.

@canbax
Copy link
Collaborator

canbax commented Oct 15, 2023

However, this type of id is not a proper selector id because it is also used as a CSS selector

You mean it is not a valid cytoscape.js selector. Right? If so where does these selectors are used? As far as I remember, they are only used in highlighting elements on hover. If it's the case, why don't we select them with selectors like [id = 'foo'] as stated https://js.cytoscape.org/#selectors/group-class-amp-id

Always replacing elementIds seems high maintenance to me. Also I see that elementId is just a string and it can be a cytoscape.js element id.

@LaraMerdol
Copy link
Collaborator Author

However, this type of id is not a proper selector id because it is also used as a CSS selector

You mean it is not a valid cytoscape.js selector. Right? If so where does these selectors are used? As far as I remember, they are only used in highlighting elements on hover. If it's the case, why don't we select them with selectors like [id = 'foo'] as stated https://js.cytoscape.org/#selectors/group-class-amp-id

Always replacing elementIds seems high maintenance to me. Also I see that elementId is just a string and it can be a cytoscape.js element id.

Yes, you are right. I changed the selectors as you suggested. Now all elementIds are in the same format without any replacements used.

Copy link
Collaborator

@canbax canbax left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1-) In some places, there might be some performance regression. O(n) is replaced with O(n^2). I think those can be done in O(n)

2-) I don't have access to deployed visual env. Please test there

3-) some time ago, there were Cypress e2e tests. Do they still run? If so, can you run them

4-) As an improvement those Cypress test could be run as a new step of the current Github Action

If you do points 1 & 2 I think it's good to merge. 3 & 4 could be future improvements. But if you could do point 3, it would be great to see this big change doesn't cause any bugs.

@@ -202,8 +201,7 @@ export class CytoscapeService {
let compoundEdgeIds2 = this._g.cy.edges('.' + C.COLLAPSED_EDGE_CLASS).map(x => x.id());
elemIds.push(...C.arrayDiff(compoundEdgeIds, compoundEdgeIds2));
// elements might already exist but hidden, so show them
this._g.viewUtils.show(this._g.cy.$(elemIds.map(x => '#' + x).join(',')));

this._g.viewUtils.show(this._g.cy.nodes().filter(node => elemIds.includes(node.id())));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: includes inside .filter() function might be O(n^2). The previous implementation might be faster. Please check this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is no longer possible to use the previous implementation as the ID cannot be utilized as a CSS selector anymore. Your observation about the runtime being O(n^2) was correct, and this is not an optimal practice. To enhance runtime to O(n), we can use a set to gather element IDs. In a set, the 'has' operation requires constant time due to the hash table implementation, but it also results in unnecessary memory consumption.

const elemIdSet = new Set(elemIds);
this._g.viewUtils.show(this._g.cy.nodes().filter(node => elemIdSet.has(node.id())));

if (!isTimeboxed) {
q = query;
}
let q = isTimeboxed
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: good that if removed. q might be a const

@@ -296,7 +296,7 @@ export class AdvancedQueriesComponent implements OnInit, OnDestroy {

private highlightSeedNodes() {
const dbIds = this.selectedNodes.map(x => x.dbId);
const seedNodes = this._g.cy.nodes(dbIds.map(x => '#n' + x).join());
const seedNodes = this._g.cy.nodes().filter(node => dbIds.includes(node.id().substring(1)));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: .includes inside .filter might be O(n^2). This is a performance regression. Can we do it in linear time?

@@ -316,7 +316,7 @@ export class AdvancedQueriesComponent implements OnInit, OnDestroy {
if (!dbIds || dbIds.length < 1) {
return;
}
const cyNodes = this._g.cy.nodes(dbIds.map(x => '#n' + x).join());
const cyNodes = this._g.cy.nodes().filter(node => dbIds.includes(node.id().substring(1)));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: .includes inside .filter might be O(n^2). This is a performance regression. Can we do it in linear time?

@LaraMerdol
Copy link
Collaborator Author

1-) In some places, there might be some performance regression. O(n) is replaced with O(n^2). I think those can be done in O(n)

2-) I don't have access to deployed visual env. Please test there

3-) some time ago, there were Cypress e2e tests. Do they still run? If so, can you run them

4-) As an improvement those Cypress test could be run as a new step of the current Github Action

If you do points 1 & 2 I think it's good to merge. 3 & 4 could be future improvements. But if you could do point 3, it would be great to see this big change doesn't cause any bugs.

I'd like to inform you of the following updates:

  1. I've come up with an alternative solution that can enhance the run time to O(n).
  2. I've tested on my local environment. If you want to test it on your local environment, you can use the new Neo4j 5.10 database running on the ivis server port:3001. The credentials to log in are username: neo4j and password: 12345678. You should also update the environment.ts file accordingly.
  3. Unfortunately, I'm unable to run Cypress e2e tests as it keeps giving me a 503: Service Unavailable error.

@LaraMerdol LaraMerdol requested a review from canbax October 18, 2023 15:14
Copy link
Collaborator

@canbax canbax left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any other issue. I don't have access to Visuall env. So I cannot test it properly with the deployed environment. But it looks OK except for the issue I mentioned

this._g.viewUtils.show(this._g.cy.$(elemIds.map(x => '#' + x).join(',')));

const elemIdSet = new Set(elemIds);
this._g.viewUtils.show(this._g.cy.nodes().filter(node => elemIdSet.has(node.id())));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: elemId could be an edge. So don't use cy.nodes()instead use cy.elements()

@LaraMerdol LaraMerdol closed this Oct 23, 2023
@LaraMerdol LaraMerdol deleted the unstable-neo4j-update branch October 23, 2023 08:04
@LaraMerdol LaraMerdol restored the unstable-neo4j-update branch October 23, 2023 11:37
@LaraMerdol LaraMerdol reopened this Oct 23, 2023
@LaraMerdol LaraMerdol closed this Oct 23, 2023
@LaraMerdol LaraMerdol deleted the unstable-neo4j-update branch October 23, 2023 11:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants