Raas Masood
Raas Masood

Reputation: 1575

querying complex type in Azure Table

I am new to NoSql concepts. Coming from a mind set of "ModelFirst" i usually design my models first. I have a model as follows.

public class Book
{
    public string Name { get; set; }
    [EntityPropertyConverter(typeof(Category))]
    public List<Category> Categories { get; set; }
}
public class Category
{
    public string Name { get; set; }
}

Student class is a complex type and

[EntityPropertyConverter]

attribute helps serialize Categories before writing to Azure Table and deserialize when reading back.

A book can belong to more than one categories. My question is if someone has to search a book by one of n number of categories, how can we do that.

Azure Table supports quires like below

TableQuery.GenerateFilterCondition("Categories", QueryComparisons.Equal, JsonConvert.SerializeObject(???))

But with this i cannot get the required result.

please do comment if my overall approach is incorrect.

Upvotes: 0

Views: 799

Answers (2)

Dogu Arslan
Dogu Arslan

Reputation: 3384

There is a way to write and query complex objects to table storage which is TableEntity.Flatten method in the SDK to flatten your object first. TableEntity.ConvertBack method to read it back and convert to original complex object. It does not do a full serialization, it keeps native properties as EntityProperty on the flattened object so each property can be queried individually.

That said the IEnumerable/ICollection type of properties are not supported by current version of TableEntity.Flatten api. However, the nuget package Object Flattener Recomposer version 2.0 supports collection/enumerable/indexed type properties:

https://www.nuget.org/packages/ObjectFlattenerRecomposer/

So you can use this nuget instead to write your complex types to table storage if your objects have those type of indexed/enumerable type properties. This nuget package does the same thing as the api s in the SDK (it is the original code behind the TableEntity.Flatten / ConvertBack methods ) but in addition it will convert enumerable/collection type properties into json strings before writing to table storage and it does creating the original complex object back in reading from the table transparently, you do not need to worry about deserializing flattened object back to the original complex type.

Coming back to your original question it is possible to write and read complex objects to table storage either by the methods I mentioned in the SDK or the latest nuget package of ObjectFlattenerRecomposer api. Though if you want to query an individual object from the List type property it will be tricky still because the List as I mentioned will be in the format of a json string on the table.

Upvotes: 0

Tom Sun
Tom Sun

Reputation: 24569

querying complex type in Azure Table

Based on my understanding, it is not supported currently. If we want to save the complex type data to the table storage, we need to SerializeObject to string and store it to the table storage

According to supported table comparison operators, we could know that it doesn't support contains. It seems that we have no way to filter the expected result.

If Azure cosmos DB(table API) is possible, I recommand that you could have a try.

Document format:

{
    "id": "test",
    "Book": {
        "Categories": [
            {
                "Name": "Category1"
            },
            {
                "Name": "Category2"
            }
        ],
        "Name": "book1"
    }
}

Query string:

SELECT * FROM root WHERE (ARRAY_CONTAINS(root.Book.Categories, {"Name": "Category2"}, true)or ARRAY_CONTAINS(root.Book.Categories, {"Name": "Category4"}, true)) 

Query from Azure portal:

![enter image description here

Upvotes: 1

Related Questions