java - neo4j - 属性自动索引器不存储值

标签 java indexing neo4j graph-databases

我遇到的问题是,在将 AutoIndex 索引设置为某个属性后,我可以添加一个键/值对,但索引不会显示它的存在。我对 neo4j 比较陌生,所以我对这个类应该做什么的概念可能是错误的。测试代码创建一个临时图形数据库,用它实例化我的数据服务类,然后创建一个用户。当数据服务类被实例化时,属性就被添加到 AutoIndex 中。您可以在 createUser() 函数内部看到,我已经打印出了刚刚创建的用户,并且应该位于 AutoIndex 中,但它打印了 null。

这是我正在测试的代码:

@Before
public void setup() throws IOException {
    graphDb = new ImpermanentGraphDatabase();
    Transaction tx = graphDb.beginTx();
    try {
        nA = graphDb.createNode();
        nB = graphDb.createNode();
        packetA = graphDb.createNode();
        packetB = graphDb.createNode();
        dataService = new DataServiceImpl(graphDb);
        tx.success();
    }
    finally
    {
        tx.finish();
    }
}

/****************** Test User Creation Functionality *******************/

@Test
public void createUser() throws ExistsException {
    Transaction tx = graphDb.beginTx();
    try {
        UserWrapper user = (UserWrapper) dataService.createUser(BigInteger.valueOf(1));
        tx.success();
    }
    finally {
        tx.finish();
    }
}

这是 DataServiceImpl 中的代码:

/**
 * Node property keys that should be auto-indexed.
 */
private static final Set<String> NODE_KEYS_INDEXABLE = new HashSet<String>(
        Arrays.asList(new String[] { UserWrapper.KEY_IDENTIFIER }));

/**
 * Relationship property keys that should be auto-index.
 */
private static final Set<String> REL_KEYS_INDEXABLE = new HashSet<String>(
        Arrays.asList(new String[] { SentWrapper.TIME_PROP }));

private void initIndices() {
/* Get the auto-indexers */
AutoIndexer<Node> nodeAutoIndexer = this.graphDb.index()
        .getNodeAutoIndexer();

RelationshipAutoIndexer relAutoIndexer = this.graphDb.index()
        .getRelationshipAutoIndexer();

this.updateIndexProperties(nodeAutoIndexer,
        DataServiceImpl.NODE_KEYS_INDEXABLE);

this.nodeIndex = nodeAutoIndexer.getAutoIndex();

this.updateIndexProperties(relAutoIndexer,
        DataServiceImpl.REL_KEYS_INDEXABLE);

this.relIndex = relAutoIndexer.getAutoIndex();
}

/**
 * Sets the indexed properties of an {@link AutoIndexer} to the specified
 * set, removing old properties and adding new ones.
 * 
 * @param autoIndexer
 *            the AutoIndexer to update.
 * @param properties
 *            the properties to be indexed.
 * @return autoIndexer, this given AutoIndexer (useful for chaining calls.)
 */
private <T extends PropertyContainer> AutoIndexer<T> updateIndexProperties(
    AutoIndexer<T> autoIndexer, Set<String> properties) {
Set<String> indexedProps = autoIndexer.getAutoIndexedProperties();
// Remove unneeded properties.
for (String prop : difference(indexedProps, properties)) {
    autoIndexer.stopAutoIndexingProperty(prop);
}

// Add new properties.
for (String prop : difference(properties, indexedProps)) {
    autoIndexer.startAutoIndexingProperty(prop);
}

// Enable the index, if needed.
if (!autoIndexer.isEnabled()) {
    autoIndexer.setEnabled(true);
}

return autoIndexer;
}

public User createUser(BigInteger identifier) throws ExistsException {
    // Verify that user doesn't already exist.
    if (this.nodeIndex.get(UserWrapper.KEY_IDENTIFIER, identifier).getSingle() != null) {
        throw new ExistsException("User with identifier '" + identifier.toString() + "' already exists.");
    }
    // Create new user.
    final Node userNode = graphDb.createNode();
    final User user = new UserWrapper(userNode);
    user.setIdentifier(identifier);

    Node userNode2 = this.nodeIndex.get(UserWrapper.KEY_IDENTIFIER, identifier).getSingle();
    System.out.println(userNode2);

    userParent.getNode().createRelationshipTo(userNode, NodeRelationships.PARENT);

    return user;
}

这是 UserWrapper 中的代码:

/**
* Mapping to neo4j key for the identifier property.
*/
//Changed to public in order to test in Test class 
static final String KEY_IDENTIFIER = "identifier";

@Override
public void setIdentifier(BigInteger newIdentity) {
    neo4jNode.setProperty(KEY_IDENTIFIER, newIdentity.toByteArray());
}

最佳答案

在哪里添加第二个用户?通过运行测试两次?然后,ImpermanentGraphDatabase 将在第二次运行之前删除所有数据(因为它用于测试)。索引发生在提交时,并聚合事务期间的所有更改,这就是为什么您在 tx (userNode2) 中看不到它。如果您愿意,可以将此检查添加到测试中(见下文)。

从您的代码中也看不到您调用 initIndices 的位置,您能指出该位置吗?另请验证自动索引器是否正在索引正确的属性。

尝试将您的测试更改为,然后第二次调用应该抛出异常:

@Test(expected = ExistsException.class)
public void createUser() throws ExistsException {
    Transaction tx = graphDb.beginTx();
    try {
        UserWrapper user = (UserWrapper) dataService.createUser(BigInteger.valueOf(1));
        tx.success();
    }
    finally {
        tx.finish();
    }
    Node userNode2 = this.graphDb.index().getNodeAutoIndexer().getAutoIndex().get(UserWrapper.KEY_IDENTIFIER, identifier).getSingle();
    assertNotNull(userNode2);

    Transaction tx = graphDb.beginTx();
    try {
        UserWrapper user = (UserWrapper) dataService.createUser(BigInteger.valueOf(1));
        tx.success();
    }
    finally {
        tx.finish();
    }
}

关于java - neo4j - 属性自动索引器不存储值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8029659/

相关文章:

sql - 搜索时CONVERT()对INDEX有什么影响?

java - 禁用 Neo4j 图形数据库的锁定?

java - 奇怪的日期格式转Java日期

java - 如何使用设备管理员获取 Android 上的当前位置(纬度、经度)?

matlab - 根据条件改变矩阵的元素

mysql - 优化mysql巨表

java - 使用 java 删除 XML 标记内的空格

java - 如何在没有 Valgrind 错误的情况下调用 JNI_CreateJavaVM?

Neo4J 通过 ID 获取节点

java - 在 neo4j java 驱动程序中获取节点的属性