Query for Edges in ArangoDB with Java throws Gson exception - java

I'm new to ArangoDB and trying to do a few very basic queries. I was successful to add vertices and edges, but the query retrieving edges always throws an exception. I tried a few different queries from the (very minimalistic) documentation and it always throws the same. Here is one of the queries:
CursorEntity<BaseDocument> r = arangoDriver.graphGetEdges("MyGraph", BaseDocument.class, "Person/1");
while (r.iterator().hasNext()){
BaseDocument d = r.iterator().next();
System.out.println(d.getDocumentHandle());
}
Or this one with the same exception:
String query = "for i in GRAPH_EDGES(#graphName, #vertexId, {direction: 'outbound', edgeCollectionRestriction: 'Friends'}) return i";
Map<String, Object> bindVars = new MapBuilder().put("graphName", "MyGraph").put("vertexId", "Person/1").get();
CursorEntity<PlainEdgeEntity> result;
try {
result = arangoDriver.executeQuery(query, bindVars, PlainEdgeEntity.class ,true, 10);
And here the exception:
Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:176)
at com.google.gson.Gson.fromJson(Gson.java:803)
at com.google.gson.Gson.fromJson(Gson.java:868)
at com.google.gson.Gson$1.deserialize(Gson.java:126)
at com.arangodb.entity.EntityDeserializers$CursorEntityDeserializer.deserialize(EntityDeserializers.java:519)
at com.arangodb.entity.EntityDeserializers$CursorEntityDeserializer.deserialize(EntityDeserializers.java:488)
at com.google.gson.TreeTypeAdapter.read(TreeTypeAdapter.java:58)
at com.google.gson.Gson.fromJson(Gson.java:803)
at com.google.gson.Gson.fromJson(Gson.java:768)
at com.google.gson.Gson.fromJson(Gson.java:717)
at com.arangodb.entity.EntityFactory.createEntity(EntityFactory.java:109)
at com.arangodb.BaseArangoDriver.createEntityImpl(BaseArangoDriver.java:270)
at com.arangodb.BaseArangoDriver.createEntity(BaseArangoDriver.java:181)
at com.arangodb.BaseArangoDriver.createEntity(BaseArangoDriver.java:219)
at com.arangodb.impl.InternalCursorDriverImpl.executeQuery(InternalCursorDriverImpl.java:78)
at com.arangodb.ArangoDriver.executeQuery(ArangoDriver.java:1877)
at com.arangodb.ArangoDriver.graphGetEdges(ArangoDriver.java:4135)
at x.y.z.database.arangodb.Arango.main(Arango.java:34)
I almost think it is a bug? Maybe a problem with newest versions? Or do i miss something?
Using latest versions.. 2.6.8 and driver 2.5.7
Update: if I use a nonexistent ID it returns zero results without exception and if i use an existing ID the same exception is thrown. that tells me that i used the right parameters, and the problem is most likely a bug..

As stj pointed out, there's a driver release fixing the initial problem: http://github.com/arangodb/arangodb-java-driver/releases .
That should work fine with the following code:
CursorEntity<BaseDocument> r = driver.graphGetEdges("myGraph",
BaseDocument.class, "Person/1");
Iterator<BaseDocument> it = r.iterator();
while {
it.hasNext()) {
BaseDocument d = it.next();
System.out.println(d.getDocumentHandle());
}
}
The example code while (r.iterator().hasNext()) { ... } won't work because it will create a new Iterator object in each iteration and thus never finish
We added more examples howto work with ArangoDB graphs in java to the learn more section of the README

Related

Using Lookback API - Query Error: incomplete intersection - Release Scope Change

I am tring to use Lookback API. I want to get all features change during a release.
What I tried :
LookbackQuery query = lookbackApi.newSnapshotQuery();
query.addFindClause("_TypeHierarchy", "PortfolioItem");
query.addFindClause("ObjectID", "280075838440");
Map previousValue = new HashMap();
previousValue.put("$exists", "true");
query.addFindClause("_PreviousValues.Release", previousValue);
query.requireFields("_SnapshotDate", "_SnapshotNumber", "FormattedID",
"Name", "Release","_PreviousValues.Release").hydrateFields("Release, _PreviousValues.Release");
LookbackResult resultSet = query.execute();
I have this exception :
Exception in thread "main" com.rallydev.lookback.LookbackException:
Query Error: incomplete intersection between 'hydrate' clause of
[Release, _PreviousValues.Release] with 'fields' clause of
[_SnapshotNumber, _PreviousValues.Release, _SnapshotDate, FormattedID,
Release, Name] at
com.rallydev.lookback.LookbackResult.validate(LookbackResult.java:101)
at
com.rallydev.lookback.LookbackApi.executeQuery(LookbackApi.java:233)
at
com.rallydev.lookback.LookbackQuery.validateAndRun(LookbackQuery.java:243)
at com.rallydev.lookback.LookbackQuery.execute(LookbackQuery.java:59)
at fr.mipih.rally.TestLoockback.main(TestLoockback.java:38)
But when I tried directly via: https://eu1.rallydev.com/analytics/v2.0/service/rally/workspace/9396539899/artifact/snapshot/query.js?hydrate=["Release","_PreviousValues.Release"]&start=1&pagesize=2000&find={$and: [{"ObjectID": 280075838440},{"_PreviousValues.Release": {"$exists":true}}]}&fields=["_SnapshotDate","_SnapshotNumber","FormattedID","Name","Release","_PreviousValues.Release"]
then I get some results!
Could you help me please and show me what I did wrong ?
The issue is in query - please wrap each field quote:
query.requireFields("_SnapshotDate", "_SnapshotNumber", "FormattedID",
"Name", "Release","_PreviousValues.Release").hydrateFields("Release", "_PreviousValues.Release");

Elasticsearch 5 - Weird error (value source config is invalid; must have either a field context or a script or marked as unwrapped)

I'm busy upgrade our Java platform from ES 2 to ES 5.4.3, So far everything is going ok, Except one query returns an error that doesn't make must sense. Has anyone seen this before?
Caused by: java.lang.IllegalStateException: value source config is invalid; must have either a field context or a script or marked as unwrapped
at org.elasticsearch.search.aggregations.support.ValuesSourceConfig.toValuesSource(ValuesSourceConfig.java:228)
at org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory.createInternal(ValuesSourceAggregatorFactory.java:51)
at org.elasticsearch.search.aggregations.AggregatorFactory.create(AggregatorFactory.java:221)
at org.elasticsearch.search.aggregations.AggregatorFactories.createSubAggregators(AggregatorFactories.java:208)
at org.elasticsearch.search.aggregations.AggregatorBase.<init>(AggregatorBase.java:78)
at org.elasticsearch.search.aggregations.bucket.BucketsAggregator.<init>(BucketsAggregator.java:48)
at org.elasticsearch.search.aggregations.bucket.terms.TermsAggregator.<init>(TermsAggregator.java:178)
at org.elasticsearch.search.aggregations.bucket.terms.AbstractStringTermsAggregator.<init>(AbstractStringTermsAggregator.java:42)
at org.elasticsearch.search.aggregations.bucket.terms.GlobalOrdinalsStringTermsAggregator.<init>(GlobalOrdinalsStringTermsAggregator.java:92)
at org.elasticsearch.search.aggregations.bucket.terms.TermsAggregatorFactory$ExecutionMode$2.create(TermsAggregatorFactory.java:277)
at org.elasticsearch.search.aggregations.bucket.terms.TermsAggregatorFactory.doCreateInternal(TermsAggregatorFactory.java:176)
at org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory.createInternal(ValuesSourceAggregatorFactory.java:55)
at org.elasticsearch.search.aggregations.AggregatorFactory.create(AggregatorFactory.java:221)
at org.elasticsearch.search.aggregations.AggregatorFactories.createTopLevelAggregators(AggregatorFactories.java:224)
at org.elasticsearch.search.aggregations.AggregationPhase.preProcess(AggregationPhase.java:55)
at org.elasticsearch.search.query.QueryPhase.execute(QueryPhase.java:106)
at org.elasticsearch.search.SearchService.loadOrExecuteQueryPhase(SearchService.java:247)
at org.elasticsearch.search.SearchService.executeQueryPhase(SearchService.java:262)
at org.elasticsearch.action.search.SearchTransportService$6.messageReceived(SearchTransportService.java:339)
at org.elasticsearch.action.search.SearchTransportService$6.messageReceived(SearchTransportService.java:336)
at org.elasticsearch.transport.RequestHandlerRegistry.processMessageReceived(RequestHandlerRegistry.java:69)
at org.elasticsearch.transport.TransportService$7.doRun(TransportService.java:627)
at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:638)
at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
... 1 more
I'm not sure without further context, but I'll note here that I resolved this error by adding a "field" property to my AggregationBuilders which I was missing before.
Before:
RangeAggregationBuilder range = AggregationBuilders.range("range_name");
After:
RangeAggregationBuilder range = AggregationBuilders.range("range_name").field("whatever.mapping.you.need");
Again, without further context it's really hard to say in your specific case. But considering this is Java (as was my issue) and not kibana-related and since mine was such an easy fix, I hope that someone (probably, future-me) that comes across this will see this and be saved much frustration.
#Override
public Map<String, Object> sumPriceAggregation(String field, int page, int size) {
if (StringUtils.isEmpty(field)) {
field = "brandName";
}
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
PageRequest pageRequest = PageRequest.of(page, size);
queryBuilder.withPageable(pageRequest);
queryBuilder.withSourceFilter(new FetchSourceFilter(new String[] {""}, null));
String termStr = field.toUpperCase();
TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms(termStr)
.field(field)
.subAggregation(AggregationBuilders.sum("totalPrice").field("price")); //be aware this is subAggregation
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
nativeSearchQueryBuilder.addAggregation(termsAggregationBuilder);
AggregatedPage<GamingLaptop> aggregatedPage = elasticsearchRestTemplate.queryForPage(
nativeSearchQueryBuilder.build(), GamingLaptop.class);
Aggregations aggregations = aggregatedPage.getAggregations();
ParsedStringTerms stringTerms = aggregations.get(termStr);
List<? extends Terms.Bucket> buckets = stringTerms.getBuckets();
HashMap<String, Object> map = new HashMap<>();
buckets.parallelStream().forEach(bucket -> {
String key = bucket.getKeyAsString();
long docCount = bucket.getDocCount();
map.put(key, docCount);
ParsedSum sum = (ParsedSum) bucket.getAggregations().asMap().get("totalPrice"); //make sure you get the aggregation here
map.putIfAbsent("sum", sum.getValue());
});
return map;
}
'value source config is invalid; must have either a field context or a script or marked as unwrapped' i encountered this error as well using spring-data-elasticsearch, please read the comments in the codes, which is my solution. Either ParsedStringTerms or TermsAggregationBuilder need to be retrieved.

How do I Append a string to a list using dynamodb sdk? (Java)

Pretty simple problem, but for some reason there is no correct documentation anywhere. Here is what I am implementing:
public static AttributeValue pushMessage(String ID,String message)
{
Map<String, AttributeValue> itemKey = mapKey(KEY, new AttributeValue(ID));
UpdateItemRequest request = new UpdateItemRequest();
request.setTableName(TABLE_NAME);
request.setKey(itemKey);
/*I don't know what to put for the update expression*/
//request.setUpdateExpression("ADD #"+LIST_NAME+" :append_value)");
request.setUpdateExpression("list_append("+LIST_NAME+", :append_value)");
request.setExpressionAttributeValues(Collections.singletonMap(":append_value", new AttributeValue(message)));
UpdateItemResult result = dynamoDB.updateItem(request);
}
I essentially just want to be able to append strings to a list I have in the items in my DB. I have tried everything the documentations have suggested(so basically 1 example) and numerous threads, but nothing works.
The error I am currently getting is:
Exception in thread "main" com.amazonaws.AmazonServiceException: Invalid UpdateExpression: Syntax error; token: "list_append", near: "list_append(" (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException;
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:1372)
at com.amazonaws.http.AmazonHttpClient.executeOneRequest(AmazonHttpClient.java:919)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:697)
at com.amazonaws.http.AmazonHttpClient.doExecute(AmazonHttpClient.java:449)
at com.amazonaws.http.AmazonHttpClient.executeWithTimer(AmazonHttpClient.java:411)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:360)
at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.doInvoke(AmazonDynamoDBClient.java:2048)
at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke(AmazonDynamoDBClient.java:2018)
at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.updateItem(AmazonDynamoDBClient.java:1845)
at DBConnector.pushMessage(DBConnector.java:486)
at DBConnector.main(DBConnector.java:506)
Use the following UpdateExpression:
String.format("SET %s = list_append(%s, :append_value)", LIST_NAME, LIST_NAME)

How to convert version one working url(endpoint) to java query using version one java REST client

I need to convert below working REST endpoint to java query
/rest-1.v1/Data/Timebox?Where=Schedule.ScheduledScopes.Name="Sample: Call Center Product"&sel=Workitems:Defect[AssetState='Closed'].Estimate.#Sum,Name,Workitems:Story[AssetState='Closed'].Estimate.#Sum
My Not working Code:
IAssetType storyType = services.getMeta().getAssetType("Timebox");
Query query = new Query(storyType, true);
IAttributeDefinition name = storyType.getAttributeDefinition("Name");
IAttributeDefinition defect_estimate = storyType.getAttributeDefinition("Workitems:Defect[AssetState='Closed'].Estimate.#Sum");
IAttributeDefinition story_estimate = storyType.getAttributeDefinition("Workitems:Story[AssetState='Closed'].Estimate.#Sum");
query.getSelection().add(name);
query.getSelection().add(defect_estimate);
query.getSelection().add(story_estimate);
//IFilterTerm activeSprint = new TokenTerm("State.Code='ACTV'");
IFilterTerm activeSprint = new TokenTerm("Schedule.ScheduledScopes.Name='Sample: Call Center Product'");
query.setFilter(activeSprint);
DefaultCategoryDataset dataset = new DefaultCategoryDataset( );
QueryResult result = services.retrieve(query);
Error i am getting:
Exception in thread "main" com.versionone.apiclient.exceptions.MetaException: Unknown AttributeDefinition: Timebox.Workitems:Defect[AssetState='Closed'].Estimate.#Sum
at com.versionone.apiclient.MetaModel.getAttributeDefinition(MetaModel.java:119)
at com.versionone.apiclient.AssetType.getAttributeDefinition(AssetType.java:96)
at v1_rest_intig.Example1.main(Example1.java:230)
what am i doing wrong??
any guidance is of great help
Thanks in advance
You are using the right attribute definition, but apparently, at some version of the API they stop translating symbols, like brakets '[' into the URL encoding ( '%5B' for open bracket) and therefore the resulting error message.
Please, try this instead:
Workitems:Defect%5BAssetState=%27128%27%5D
for your attributes definition for the Defect/Story AssetType.
Let me know if this works.
TIA,

mongoDB: cursor notimeout setting isn't working in java client

i set an 'notimeout' option to a dbcursor in java:
BasicDBObject nearbyQueries = new BasicDBObject("$gt", 0)
.append("$lte", 2);
DBCursor trueClassInstances = locationsCollection.find(new BasicDBObject("distanceFromHotel", nearbyQueries)).addOption(Bytes.QUERYOPTION_NOTIMEOUT).limit(100000);
double counter = 0;
int currentPresent = 0;
for (DBObject instance : trueClassInstances) {
...
}
even with this option i set, this exception is thrown:
Exception in thread "main" com.mongodb.MongoCursorNotFoundException: Query failed with error code -5 and error message 'Cursor 1876954464377 not found on server XXXXXX:27017' on server XXXXXXXX:27017
at com.mongodb.connection.GetMoreProtocol.receiveMessage(GetMoreProtocol.java:115)
at com.mongodb.connection.GetMoreProtocol.execute(GetMoreProtocol.java:68)
at com.mongodb.connection.GetMoreProtocol.execute(GetMoreProtocol.java:37)
at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:155)
at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:219)
at com.mongodb.connection.DefaultServerConnection.getMore(DefaultServerConnection.java:194)
at com.mongodb.operation.QueryBatchCursor.getMore(QueryBatchCursor.java:197)
at com.mongodb.operation.QueryBatchCursor.hasNext(QueryBatchCursor.java:93)
at com.mongodb.MongoBatchCursorAdapter.hasNext(MongoBatchCursorAdapter.java:46)
at com.mongodb.DBCursor.hasNext(DBCursor.java:152)
at locationExtraction.DistanceClassification.FeatureAnalyzer.main(FeatureAnalyzer.java:27)
FeatureAnalyzer.java:27 is the for loop line.
this problem appear in other project with similar setting...
what am i doing wrong? maybe my choice of 'for' loop instead of this kind of iteration can cause this strange behavior?
while(cursor.hasNext())
{
DBObject next = cursor.next();
}
Thanks
Looks like you are not able to process each batch within time limit. Try reducing batch size so that each batch could be consumed before time runs out. This should help.
cursor.addOption(com.mongodb.Bytes.QUERYOPTION_NOTIMEOUT).batchSize(100)
so the problem is solved.
this is very strange but there is a problem with using 'for' loop for iterating on cursor. so dont do it like i did it, use 'while' loop:
while(cursor.hasNext())
{
DBObject next = cursor.next();
}
before use cursor.hasNext() and cursor.next() to do business logical, just before you get the mongo cursor, invoke FindIterable object's noCursorTimeout(true) method. for example:
FindIterable<Document> findIterable = sentenceColl.find(condition);
// set no timeout
findIterable.noCursorTimeout(true);
MongoCursor<Document> mongoCursor = findIterable.iterator();
while (mongoCursor.hasNext()) {
mongoCursor.next();
}
try this:
Iterator<BasicDBObject> it = null;
it = coll.find("{"field": {$in:#}}", fieldList).with(
new QueryModifier() {
public void modify(DBCursor cursor) {
cursor.setOptions(Bytes.QUERYOPTION_NOTIMEOUT);
}
}
).as(BasicDBObject.class);

Categories