neo4j - Свойство AutoIndexer не хранит значения - PullRequest
0 голосов
/ 06 ноября 2011

Проблема, с которой я сталкиваюсь, заключается в том, что после того, как я сделаю индекс AutoIndex определенным свойством, я могу добавить пару ключ / значение, и индекс не покажет, что он там есть. Я относительно новичок в neo4j, поэтому мое представление о том, что должен делать этот класс, может быть неверным. Тестовый код создает базу данных с непостоянными графами, создает для нее экземпляр моего класса обслуживания данных, а затем создает пользователя. Когда создается экземпляр класса обслуживания данных, тогда свойства добавляются в AutoIndex. Вы можете видеть внутри функции createUser (), я распечатал пользователя, которого я только что создал и должен быть в AutoIndex, но он печатает ноль.

Это код, который я тестирую:

@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());
}

Ответы [ 2 ]

2 голосов
/ 07 ноября 2011

Куда вы добавляете второго пользователя?Запустив тест дважды?Тогда 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();
    }
}
0 голосов
/ 07 ноября 2011

Я нашел ответ на этот вопрос косвенно из ответа Михаила. Я понял, что с помощью assertNotNull (userNode2); не удалось, если это было сразу после dataService.createUser (), но прошло, если это было после блока try finally. Таким образом, если бы я хотел использовать созданный мной узел, мне нужно было бы создать еще один блок try finally после того, который создает узел для его использования. Я полагаю, что это потому, что пользователь не добавляется в индекс до тех пор, пока не будет вызвана tx.success (), хотя это всего лишь предположение.

...