arangodb-net-standard icon indicating copy to clipboard operation
arangodb-net-standard copied to clipboard

ArangoDBNetStandard.IndexApi.IIndexApiClient.GetIndexAsync fails to deserialize inverted indexes

Open lukebobwatson opened this issue 1 year ago • 1 comments

If I first post an inverted index (i.e., ArangoDBNetStandard.IndexApi.IIndexApiClient.PostInvertedIndexAsync) and then later try to get that inverted index (i.e., ArangoDBNetStandard.IndexApi.IIndexApiClient.GetIndexAsync) I get the following deserialization error:

Unexpected character encountered while parsing value: {. Path 'fields', line 1, position 292.

I assume this is related to issues #443 #470

Call stack:

   at Newtonsoft.Json.JsonTextReader.ReadStringValue(ReadType readType)
   at Newtonsoft.Json.JsonTextReader.ReadAsString()
   at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)
   at ArangoDBNetStandard.Serialization.JsonNetApiClientSerialization.DeserializeFromStream[T](Stream stream)
   at ArangoDBNetStandard.Serialization.JsonNetApiClientSerialization.<DeserializeFromStreamAsync>d__1`1.MoveNext()
   at ArangoDBNetStandard.ApiClientBase.<DeserializeJsonFromStreamAsync>d__4`1.MoveNext()
   at ArangoDBNetStandard.IndexApi.IndexApiClient.<GetIndexAsync>d__4.MoveNext()

Reproduction:

var collection = new PostIndexQuery { CollectionName = "document" };
var postBody = new PostInvertedIndexBody
{
    Name = "inverted",
    Fields = new List<InvertedIndexField> { new InvertedIndexField { Name = "description", Analyzer = "text_en" } }
};
var index = await db.Index.PostInvertedIndexAsync(collection, postBody);
var response = await db.Index.GetIndexAsync(index.Id);

I think this has to do with the discrepancy between the Fields property on the InvertedIndexBody used to create the inverted index versus the IndexResponseBase used to fetch the index.

I made a custom IndexApiClient and introduced this method with a nearly identical implementation to GetIndexAsync:

public virtual async Task<InvertedIndexResponse> GetInvertedIndexAsync(string indexId, CancellationToken token = default(CancellationToken))

And this did enable me to fetch the inverted index.

Perhaps we need a generic GetIndexAsync?

lukebobwatson avatar Oct 08 '24 19:10 lukebobwatson

<PackageReference Include="ArangoDBNetStandard" Version="2.0.1/>"

lukebobwatson avatar Oct 08 '24 19:10 lukebobwatson

Thanks for opening this issue.

I made a custom IndexApiClient and introduced this method with a nearly identical implementation to GetIndexAsync: And this did enable me to fetch the inverted index.

I think this is a good approach. @JLedel mentioned that this is what the Java library does.

@lukebobwatson Would you be ok to open a PR?

DiscoPYF avatar Oct 29 '25 10:10 DiscoPYF

I suspect we have the same issue with GetAllCollectionIndexesAsync, to be confirmed. 🤔

DiscoPYF avatar Oct 29 '25 12:10 DiscoPYF

@DiscoPYF I'd be happy to open a PR for this. I'll wait for you to confirm whether the same issue exists for GetAllCollectionIndexesAsync? That might change our approach, I suppose.

lukebobwatson avatar Nov 07 '25 14:11 lukebobwatson