/** * Find node by exact match. * * <p>NOTE: Spaces in the URI have to be encoded as +%20+. */ @Documented @Test public void shouldAddToIndexAndRetrieveItByExactMatch() throws Exception { String indexName = "favorites"; String key = "key"; String value = "the value"; long nodeId = createNode(); value = URIHelper.encode(value); // implicitly create the index JaxRsResponse response = RestRequest.req() .post( functionalTestHelper.indexNodeUri(indexName), createJsonStringFor(nodeId, key, value)); assertEquals(201, response.getStatus()); // search it exact String entity = gen() .noGraph() .expectedStatus(200) .get(functionalTestHelper.indexNodeUri(indexName, key, URIHelper.encode(value))) .entity(); Collection<?> hits = (Collection<?>) JsonHelper.jsonToSingleValue(entity); assertEquals(1, hits.size()); }
@Test public void shouldBeAbleToIndexValuesContainingSpaces() throws Exception { final long nodeId = helper.createNode(); final String key = "key"; final String value = "value with spaces in it"; String indexName = "spacey-values"; helper.createNodeIndex(indexName); final RestRequest request = RestRequest.req(); JaxRsResponse response = request.post( functionalTestHelper.indexNodeUri(indexName), createJsonStringFor(nodeId, key, value)); assertEquals(Status.CREATED.getStatusCode(), response.getStatus()); URI location = response.getLocation(); response.close(); response = request.get(functionalTestHelper.indexNodeUri(indexName, key, URIHelper.encode(value))); assertEquals(Status.OK.getStatusCode(), response.getStatus()); Collection<?> hits = (Collection<?>) JsonHelper.jsonToSingleValue(response.getEntity()); assertEquals(1, hits.size()); response.close(); CLIENT.resource(location).delete(); response = request.get(functionalTestHelper.indexNodeUri(indexName, key, URIHelper.encode(value))); hits = (Collection<?>) JsonHelper.jsonToSingleValue(response.getEntity()); assertEquals(0, hits.size()); }
@Test public void shouldGet200AndArrayOfNodeRepsWhenGettingFromIndex() throws PropertyValueException { String key = "myKey"; String value = "myValue"; String name1 = "Thomas Anderson"; String name2 = "Agent Smith"; String indexName = "matrix"; final RestRequest request = RestRequest.req(); JaxRsResponse responseToPost = request.post(functionalTestHelper.nodeUri(), "{\"name\":\"" + name1 + "\"}"); assertEquals(201, responseToPost.getStatus()); String location1 = responseToPost.getHeaders().getFirst(HttpHeaders.LOCATION); responseToPost.close(); responseToPost = request.post(functionalTestHelper.nodeUri(), "{\"name\":\"" + name2 + "\"}"); assertEquals(201, responseToPost.getStatus()); String location2 = responseToPost.getHeaders().getFirst(HttpHeaders.LOCATION); responseToPost.close(); responseToPost = request.post( functionalTestHelper.indexNodeUri(indexName), createJsonStringFor(functionalTestHelper.getNodeIdFromUri(location1), key, value)); assertEquals(201, responseToPost.getStatus()); String indexLocation1 = responseToPost.getHeaders().getFirst(HttpHeaders.LOCATION); responseToPost.close(); responseToPost = request.post( functionalTestHelper.indexNodeUri(indexName), createJsonStringFor(functionalTestHelper.getNodeIdFromUri(location2), key, value)); assertEquals(201, responseToPost.getStatus()); String indexLocation2 = responseToPost.getHeaders().getFirst(HttpHeaders.LOCATION); Map<String, String> uriToName = new HashMap<>(); uriToName.put(indexLocation1, name1); uriToName.put(indexLocation2, name2); responseToPost.close(); JaxRsResponse response = RestRequest.req().get(functionalTestHelper.indexNodeUri(indexName, key, value)); assertEquals(200, response.getStatus()); Collection<?> items = (Collection<?>) JsonHelper.jsonToSingleValue(response.getEntity()); int counter = 0; for (Object item : items) { Map<?, ?> map = (Map<?, ?>) item; Map<?, ?> properties = (Map<?, ?>) map.get("data"); assertNotNull(map.get("self")); String indexedUri = (String) map.get("indexed"); assertEquals(uriToName.get(indexedUri), properties.get("name")); counter++; } assertEquals(2, counter); response.close(); }
/** Remove all entries with a given node from an index. */ @Documented @Test public void shouldBeAbleToRemoveIndexingById() { String key1 = "kvkey1"; String key2 = "kvkey2"; String value1 = "value1"; String value2 = "value2"; String indexName = "kvnode"; long node = helper.createNode(MapUtil.map(key1, value1, key1, value2, key2, value1, key2, value2)); helper.addNodeToIndex(indexName, key1, value1, node); helper.addNodeToIndex(indexName, key1, value2, node); helper.addNodeToIndex(indexName, key2, value1, node); helper.addNodeToIndex(indexName, key2, value2, node); gen() .noGraph() .expectedStatus(204) .delete(functionalTestHelper.indexNodeUri(indexName) + "/" + node); assertEquals(0, helper.getIndexedNodes(indexName, key1, value1).size()); assertEquals(0, helper.getIndexedNodes(indexName, key1, value2).size()); assertEquals(0, helper.getIndexedNodes(indexName, key2, value1).size()); assertEquals(0, helper.getIndexedNodes(indexName, key2, value2).size()); }
@Test public void shouldGetNodeRepresentationFromIndexUri() throws JsonParseException { long nodeId = helper.createNode(); String key = "key2"; String value = "value"; String indexName = "mindex"; helper.createNodeIndex(indexName); JaxRsResponse response = RestRequest.req() .post( functionalTestHelper.indexNodeUri(indexName), createJsonStringFor(nodeId, key, value)); assertEquals(Status.CREATED.getStatusCode(), response.getStatus()); String indexUri = response.getHeaders().getFirst("Location"); response = RestRequest.req().get(indexUri); assertEquals(200, response.getStatus()); String entity = response.getEntity(); Map<String, Object> map = JsonHelper.jsonToMap(entity); assertNotNull(map.get("self")); }
/** Delete node index. */ @Documented @Test public void shouldReturn204WhenRemovingNodeIndexes() { String indexName = "kvnode"; helper.createNodeIndex(indexName); gen().noGraph().expectedStatus(204).delete(functionalTestHelper.indexNodeUri(indexName)); }
@Test public void orderedResultsAreSupersetOfUnordered() throws Exception { // Given String indexName = "bobTheIndex"; String key = "Name"; String value = "Builder"; long node = helper.createNode(MapUtil.map(key, value)); helper.addNodeToIndex(indexName, key, value, node); helper.addNodeToIndex(indexName, "Gender", "Male", node); String entity = gen() .expectedStatus(200) .get( functionalTestHelper.indexNodeUri(indexName) + "?query=Name:Build~0.1%20AND%20Gender:Male") .entity(); Collection<?> hits = (Collection<?>) JsonHelper.jsonToSingleValue(entity); LinkedHashMap<String, String> nodeMapUnordered = (LinkedHashMap) hits.iterator().next(); // When entity = gen() .expectedStatus(200) .get( functionalTestHelper.indexNodeUri(indexName) + "?query=Name:Build~0.1%20AND%20Gender:Male&order=score") .entity(); hits = (Collection<?>) JsonHelper.jsonToSingleValue(entity); LinkedHashMap<String, String> nodeMapOrdered = (LinkedHashMap) hits.iterator().next(); // Then for (Map.Entry<String, String> unorderedEntry : nodeMapUnordered.entrySet()) { assertEquals( "wrong entry for key: " + unorderedEntry.getKey(), unorderedEntry.getValue(), nodeMapOrdered.get(unorderedEntry.getKey())); } assertTrue( "There should be only one extra value for the ordered map", nodeMapOrdered.size() == nodeMapUnordered.size() + 1); }
@Test public void shouldRespondWith400WhenSendingCorruptJson() throws Exception { final String indexName = "botherable-index"; helper.createNodeIndex(indexName); final String corruptJson = "{\"key\" \"myKey\"}"; JaxRsResponse response = RestRequest.req().post(functionalTestHelper.indexNodeUri(indexName), corruptJson); assertEquals(400, response.getStatus()); response.close(); }
@Test public void shouldGet200WhenGettingNodesFromIndexWithNoHits() { String indexName = "empty-index"; helper.createNodeIndex(indexName); JaxRsResponse response = RestRequest.req() .get( functionalTestHelper.indexNodeUri( indexName, "non-existent-key", "non-existent-value")); assertEquals(200, response.getStatus()); response.close(); }
@Test public void shouldGetTrinityWhenSearchingForHer() { JaxRsResponse response = RestRequest.req() .get( functionalTestHelper.indexNodeUri("node", "name", "Trinity"), MediaType.TEXT_HTML_TYPE); assertEquals(Status.OK.getStatusCode(), response.getStatus()); String entity = response.getEntity(); assertTrue(entity.contains("Trinity")); assertValidHtml(entity); response.close(); }
/** * Add node to index. * * <p>Associates a node with the given key/value pair in the given index. * * <p>NOTE: Spaces in the URI have to be encoded as +%20+. * * <p>CAUTION: This does *not* overwrite previous entries. If you index the same key/value/item * combination twice, two index entries are created. To do update-type operations, you need to * delete the old entry before adding a new one. */ @Documented @Test public void shouldAddToIndex() throws Exception { final String indexName = "favorites"; final String key = "some-key"; final String value = "some value"; long nodeId = createNode(); // implicitly create the index gen() .noGraph() .expectedStatus(201) .payload( JsonHelper.createJsonFrom( generateNodeIndexCreationPayload(key, value, functionalTestHelper.nodeUri(nodeId)))) .post(functionalTestHelper.indexNodeUri(indexName)); // look if we get one entry back JaxRsResponse response = RestRequest.req() .get(functionalTestHelper.indexNodeUri(indexName, key, URIHelper.encode(value))); String entity = response.getEntity(); Collection<?> hits = (Collection<?>) JsonHelper.jsonToSingleValue(entity); assertEquals(1, hits.size()); }
/** * POST ${org.neo4j.server.rest.web}/index/node/{indexName}/{key}/{value} * "http://uri.for.node.to.index" */ @Test public void shouldRespondWith201CreatedWhenIndexingJsonNodeUri() { final long nodeId = helper.createNode(); final String key = "key"; final String value = "value"; final String indexName = "testy"; helper.createNodeIndex(indexName); JaxRsResponse response = RestRequest.req() .post( functionalTestHelper.indexNodeUri(indexName), createJsonStringFor(nodeId, key, value)); assertEquals(201, response.getStatus()); assertNotNull(response.getHeaders().getFirst("Location")); assertEquals(Arrays.asList((Long) nodeId), helper.getIndexedNodes(indexName, key, value)); }
/** * Find node by query. * * <p>The query language used here depends on what type of index you are querying. The default * index type is Lucene, in which case you should use the Lucene query language here. Below an * example of a fuzzy search over multiple keys. * * <p>See: {lucene-base-uri}/queryparsersyntax.html * * <p>Getting the results with a predefined ordering requires adding the parameter * * <p>`order=ordering` * * <p>where ordering is one of index, relevance or score. In this case an additional field will be * added to each result, named score, that holds the float value that is the score reported by the * query result. */ @Documented @Test public void shouldAddToIndexAndRetrieveItByQuery() throws PropertyValueException { String indexName = "bobTheIndex"; String key = "Name"; String value = "Builder"; long node = helper.createNode(MapUtil.map(key, value)); helper.addNodeToIndex(indexName, key, value, node); helper.addNodeToIndex(indexName, "Gender", "Male", node); String entity = gen() .noGraph() .expectedStatus(200) .get( functionalTestHelper.indexNodeUri(indexName) + "?query=Name:Build~0.1%20AND%20Gender:Male") .entity(); Collection<?> hits = (Collection<?>) JsonHelper.jsonToSingleValue(entity); assertEquals(1, hits.size()); LinkedHashMap<String, String> nodeMap = (LinkedHashMap) hits.iterator().next(); assertNull("score should not be present when not explicitly ordering", nodeMap.get("score")); }
@Test public void shouldAddToIndexAndRetrieveItByQuerySorted() throws PropertyValueException { String indexName = "bobTheIndex"; String key = "Name"; long node1 = helper.createNode(); long node2 = helper.createNode(); helper.addNodeToIndex(indexName, key, "Builder2", node1); helper.addNodeToIndex(indexName, "Gender", "Male", node1); helper.addNodeToIndex(indexName, key, "Builder", node2); helper.addNodeToIndex(indexName, "Gender", "Male", node2); String entity = gen() .expectedStatus(200) .get( functionalTestHelper.indexNodeUri(indexName) + "?query=Name:Build~0.1%20AND%20Gender:Male&order=relevance") .entity(); Collection<?> hits = (Collection<?>) JsonHelper.jsonToSingleValue(entity); assertEquals(2, hits.size()); Iterator<LinkedHashMap<String, Object>> it = (Iterator<LinkedHashMap<String, Object>>) hits.iterator(); LinkedHashMap<String, Object> node2Map = it.next(); LinkedHashMap<String, Object> node1Map = it.next(); float score2 = ((Double) node2Map.get("score")).floatValue(); float score1 = ((Double) node1Map.get("score")).floatValue(); assertTrue( "results returned in wrong order for relevance ordering", ((String) node2Map.get("self")).endsWith(Long.toString(node2))); assertTrue( "results returned in wrong order for relevance ordering", ((String) node1Map.get("self")).endsWith(Long.toString(node1))); /* * scores are always the same, just the ordering changes. So all subsequent tests will * check the same condition. */ assertTrue("scores are reversed", score2 > score1); entity = gen() .expectedStatus(200) .get( functionalTestHelper.indexNodeUri(indexName) + "?query=Name:Build~0.1%20AND%20Gender:Male&order=index") .entity(); hits = (Collection<?>) JsonHelper.jsonToSingleValue(entity); assertEquals(2, hits.size()); it = (Iterator<LinkedHashMap<String, Object>>) hits.iterator(); /* * index order, so as they were added */ node1Map = it.next(); node2Map = it.next(); score1 = ((Double) node1Map.get("score")).floatValue(); score2 = ((Double) node2Map.get("score")).floatValue(); assertTrue( "results returned in wrong order for index ordering", ((String) node1Map.get("self")).endsWith(Long.toString(node1))); assertTrue( "results returned in wrong order for index ordering", ((String) node2Map.get("self")).endsWith(Long.toString(node2))); assertTrue("scores are reversed", score2 > score1); entity = gen() .expectedStatus(200) .get( functionalTestHelper.indexNodeUri(indexName) + "?query=Name:Build~0.1%20AND%20Gender:Male&order=score") .entity(); hits = (Collection<?>) JsonHelper.jsonToSingleValue(entity); assertEquals(2, hits.size()); it = (Iterator<LinkedHashMap<String, Object>>) hits.iterator(); node2Map = it.next(); node1Map = it.next(); score2 = ((Double) node2Map.get("score")).floatValue(); score1 = ((Double) node1Map.get("score")).floatValue(); assertTrue( "results returned in wrong order for score ordering", ((String) node2Map.get("self")).endsWith(Long.toString(node2))); assertTrue( "results returned in wrong order for score ordering", ((String) node1Map.get("self")).endsWith(Long.toString(node1))); assertTrue("scores are reversed", score2 > score1); }