Neo4j graph.index().forNodes not finding nodes

匆匆过客 提交于 2019-12-13 07:05:00

问题


I'm trying to create unique nodes of type TEST with a unique property of "id".

However the forNodes() method is not detecting duplicates, is there any better method using Java API only and why does the below not work?

public class Neo4jTest
{
    public static void main(String args[])
    {
        GraphDatabaseService graph = new TestGraphDatabaseFactory().newImpermanentDatabase();

        Label testLabel = new Label()
        {
            @Override
            public String name()
            {
                return "TEST";
            }
        };

        try (Transaction tx = graph.beginTx())
        {
            graph.schema()
                    .constraintFor(testLabel)
                    .assertPropertyIsUnique("id")
                    .create();
            tx.success();
        }

        try (Transaction tx = graph.beginTx())
        {
            int k = 99;
            for (int i = 0; i < 4; i++)
            {
                System.out.println("indexing... i="+i);
                Index<Node> testIndex = graph.index().forNodes(testLabel.name());
                IndexHits<Node> testIterator = testIndex.get("id", k);

                if (!testIterator.hasNext())
                {
                    System.out.println("creating node... i="+i);
                    Node testNode = graph.createNode(testLabel);
                    testNode.setProperty("id", k);
                    tx.success();
                }
            }
        }
    }
}

The above returns:

indexing... i=0
creating node... i=0
indexing... i=1
creating node... i=1
Exception in thread "main" org.neo4j.graphdb.ConstraintViolationException: Node 0 already exists with label TEST and property "id"=[99]

shouldn't the above detect when i=1 that there's already a node with id = 99???

EDIT: same error also in different transactions..

public class Neo4jTest
{

    public static void main(String args[])
    {
        GraphDatabaseService graph = new TestGraphDatabaseFactory().newImpermanentDatabase();

        Label testLabel = new Label()
        {
            @Override
            public String name()
            {
                return "TEST";
            }
        };

        try (Transaction tx = graph.beginTx())
        {
            graph.schema()
                    .constraintFor(testLabel)
                    .assertPropertyIsUnique("id")
                    .create();
            tx.success();
        }

        int k = 99;

        try (Transaction tx = graph.beginTx())
        {
            System.out.println("indexing... i=" + 0);
            Index<Node> testIndex = graph.index().forNodes(testLabel.name());
            IndexHits<Node> testIterator = testIndex.get("id", k);

            if (!testIterator.hasNext())
            {
                System.out.println("creating node... i=" + 0);
                Node testNode = graph.createNode(testLabel);
                testNode.setProperty("id", k);

            }
            tx.success();
        }

        try (Transaction tx = graph.beginTx())
        {
            System.out.println("indexing... i=" + 1);
            Index<Node> testIndex = graph.index().forNodes(testLabel.name());
            IndexHits<Node> testIterator = testIndex.get("id", k);

            if (!testIterator.hasNext())
            {
                System.out.println("creating node... i=" + 1);
                Node testNode = graph.createNode(testLabel);
                testNode.setProperty("id", k);
            }
            tx.success();
        }
    }
}

回答1:


The real problem that you are finding is that testIterator is returning false when it should return true. When i == 1 the iterator should have returned !true because it already has one no further insertion should have happened.

But it is not working as designed then it proceeds to insert and you get an exception as it should be. The graph is recognizing the uniqueness violation.

What you don't know is if the iterator is being cached without updating after the transaction is committed

if (!testIterator.hasNext())
{
...
}

Notice that going from 0 to 1 nodes does NOT involve any uniqueness. This is where the iterator is failing: not being updated



来源:https://stackoverflow.com/questions/42255542/neo4j-graph-index-fornodes-not-finding-nodes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!