Filtering content

Hello all,

I’m currently integrating UGC into my project and plan to use filtering to organize content in the user interface starting with upload or updated dates (daily, weekly, etc.). I don’t know if it’s just my failing but I can’t find any documentation about how to write the filter strings. Does it follow a common formatting or is it custom? Could anyone point me in the right direction or provide some samples as what is expected?

The only place I found some information about that was in the API documentation page.
https://services.docs.unity.com/user-generated-content-client/v1/#tag/Content/operation/SearchContent

I did some tests and the code below worked fine:

var getContentsArgs = new GetContentsArgs()
{
    Filters = new List<string>() { "createdAt,gte,2019-08-24T14:15:22Z" }
};
var contents = await UgcService.Instance.GetContentsAsync(getContentsArgs);

Also, it seems that you can apply a filter in all fields from the
Unity.Services.Ugc.Content class.

Can I apply filters to metadata? I have tried for a long time but still cannot get it to work.

Here is my code:

private async Task SetupAsync()
{
    var contents = await UgcService.Instance.GetPlayerContentsAsync(new GetPlayerContentsArgs
    {
        Filters = new List<string> {"deletedAt,eq,null"},
    });
    foreach (var content in contents.Results)
    {
        Debug.Log($"Deleting content: {content.Id}");
        await UgcService.Instance.DeleteContentAsync(content.Id);
    }

    for (var i = 1; i <= 5; i++)
    {
        await CreateContentAsync(i);
    }
}

private async Task CreateContentAsync(int index)
{
    var byteArray = Encoding.UTF8.GetBytes($"Content{index}");
    using var contentStream = new MemoryStream(byteArray);

    var name = $"Name{index}";
    Debug.Log($"Creating content: [{index}] {name}");

    await UgcService.Instance.CreateContentAsync(new CreateContentArgs(name, $"Description{index}", contentStream)
    {
        CustomId = $"CustomId{index}",
        Metadata = $"{{\"key\":{index}}}",
        IsPublic = true,
    });
}

private async UniTask TestFilterAsync()
{
    await FilterContentsAsync("name,eq,Name2"); // Works as expected, returns "Name2"
    await FilterContentsAsync("name,gt,Name2"); // Failed with: Unity.Services.Core.RequestFailedException: The service is unavailable - please try again later.
    await FilterContentsAsync("name,gte,Name2"); // Failed with: Unity.Services.Core.RequestFailedException: The service is unavailable - please try again later.
    await FilterContentsAsync("description,gt,Name2"); // Failed with: Unity.Services.Core.RequestFailedException: The service is unavailable - please try again later.
    await FilterContentsAsync("Description,gt,Name2"); // Failed with: Unity.Services.Core.RequestFailedException: The service is unavailable - please try again later.
    await FilterContentsAsync("customId,gt,Name2"); // Failed with: Unity.Services.Core.RequestFailedException: The service is unavailable - please try again later.
    await FilterContentsAsync("CustomId,gt,Name2"); // Failed with: Unity.Services.Core.RequestFailedException: The service is unavailable - please try again later.

    await FilterContentsAsync("key,gt,2"); // Unexpected, returns "Name1"
    await FilterContentsAsync("metadata.key,gt,2"); // Unexpected, returns "Name1"
    await FilterContentsAsync("Metadata.key,gt,2"); // Unexpected, returns "Name1"
    await FilterContentsAsync("content.metadata.key,gt,2"); // Unexpected, returns "Name1"
    await FilterContentsAsync("Content.Metadata.key,gt,2"); // Unexpected, returns "Name1"
}

private async Task FilterContentsAsync(string filter)
{
    try
    {
        var getContentsArgs = new GetContentsArgs()
        {
            Limit = 1,
            Filters = new List<string> {"deletedAt,eq,null", filter},
            IncludeTotal = true,
        };
        getContentsArgs.AddSortBy(SearchContentSortBy.Name, false);
        var response = await UgcService.Instance.GetContentsAsync(getContentsArgs);
        Debug.Log($"Filtered contents with filter = \"{filter}\": Total={response.Total}, Count={response.Results.Count}, Name={response.Results.FirstOrDefault()?.Name}");
    }
    catch (Exception e)
    {
        Debug.LogError($"Filtered contents with filter = \"{filter}\" failed: {e}");
    }
}