docs.unity3d.com
Search Results for

    Show / Hide Table of Contents

    Use case: Querying metadata

    How do I...?

    Set up a IMetadataRepository

    
    public IMetadataRepository CreateMetadataRepository(IServiceHttpClient serviceHttpClient, IServiceHostResolver serviceHostResolver, ProjectId projectId, AssetId assetId, DatasetId datasetId )
    {
        return new MetadataRepository(serviceHttpClient, serviceHostResolver, projectId, assetId, datasetId);
    }
    
    

    IMetadataRepository is the first entry point for any metadata query. The constructor of the default implementation requires:

    • An instance of IServiceHttpClient and IServiceHostREsolver. See Best practices: dependency injection page of the Identity package documentation for more information.
    • A projectId, assetId and datasetId. See Unity Cloud Common documentation for more information.

    Query metadata

    
    public async Task QueryingMetadata(IMetadataRepository metadataRepository)
    {
        // Perform the query
        MatchCollection result = await metadataRepository.Query().ExecuteAsync();
    
        // Iterate through the match collection
        foreach (InstanceId ownerId in result.Keys)
        {
            // Each entries in the MatchCollection is attached to a single ownerId, and contains a MetadataObject
            var metadata = result[ownerId];
        }
    }
    
    

    With a IMetadataRepository, you can perform a query by combining the Query and the ExecuteAsync methods.

    Once the query has been executed, you can easily iterate through the matches which each hold:

    • OwnerId to point to the single Owner that contains metadata
    • RequestedMetadata to expose the queried metadata attached to this owner.

    Use filters to build advanced queries

    
    public async Task QueryingMetadataAdvanced(IMetadataRepository metadataRepository, string[] rootKeysToQuery, InstanceId[] ownerIdsToConsider, IEnumerable<string> pathToKey, string expectedValue)
    {
        MatchCollection result = await metadataRepository.Query()
            .Select(rootKeysToQuery)
            .IncludedIn(ownerIdsToConsider)
            .WhereKeyEquals(pathToKey, expectedValue)
            .ExecuteAsync();
    }
    
    

    The query described in the section above is the most standard query that you could expect, as it doesn't use any filter. Following a LINQ-like approach, the query system provides a way to build more advanced queries.

    SELECT filter, to query a subset of the metadata

    
    public async Task QueryingMetadataWithSelectFilter(IMetadataRepository metadataRepository, string[] rootKeysToQuery)
    {
        // Query will return matches whose metadata content is restricted to the specified keys
        MatchCollection result = await metadataRepository.Query()
            .Select(rootKeysToQuery)
            .ExecuteAsync();
    }
    
    

    Using the Select method, you can specialize the query to ensure that only a specific set of root keys will be included in the response.

    Note

    This will also forcefully add the key to every fetched metadata. If it didn't originally contain it, it will appear as empty.

    SELECT-ALL filter, to query everything from the metadata

    
    public async Task QueryingMetadataWithSelectAllFilter(IMetadataRepository metadataRepository)
    {
        // Query will return matches whose metadata content is everything
        MatchCollection result = await metadataRepository.Query()
            .SelectAll()
            .ExecuteAsync();
    }
    
    

    Using the SelectAll method, the whole metadata content for every instances will be included in the response.

    SELECT-ONLY-ID filter, to query no metadata content

    
    public async Task QueryingMetadataWithSelectOnlyIdFilter(IMetadataRepository metadataRepository)
    {
        // Query will return matches without metadata content, simply the id
        MatchCollection result = await metadataRepository.Query()
            .SelectOnlyId()
            .ExecuteAsync();
    }
    
    

    Using the SelectOnlyId method, no metadata will be returned. The result will only contains the ids. This is especially useful when used with a Where filter.

    INCLUDED-IN filter, to query a subset of dataset instances

    
    public async Task QueryingMetadataWithIncludedInFilter(IMetadataRepository metadataRepository, InstanceId[] ownerIdsToConsider)
    {
        // Query will only return matches that are attached to the specified owner Ids
        MatchCollection result = await metadataRepository.Query()
            .IncludedIn(ownerIdsToConsider)
            .ExecuteAsync();
    }
    
    

    Using the IncludedIn method, you can specialize the query to ensure that only a specific subset of instances in the dataset will be included in the response.

    WHERE filter, to apply a metadata-based condition

    
    public async Task QueryingMetadataWithWhereFilter(IMetadataRepository metadataRepository, IEnumerable<string> pathToKey, string expectedValue)
    {
        // Query will only contain matches that follow the specified criterium
        MatchCollection result = await metadataRepository.Query()
            .WhereKeyEquals(pathToKey, expectedValue)
            .ExecuteAsync();
    }
    
    

    Using the WhereKeyEquals method, you can specialize the query to ensure that the matches to be included in the response follow a specific metadata-based condition:

    • Metadata should contain a specific key.
    • This key should have a value exactly equal to a constant value.

    LIMIT-TO filter, to specify the number of metadata records to return

    
    public async Task QueryingMetadataWithWhereFilter(IMetadataRepository metadataRepository, int amount)
    {
        // Query will only contain matches that follow the specified criterium
        MatchCollection result = await metadataRepository.Query()
            .LimitTo(amount)
            .ExecuteAsync();
    }
    
    

    Using the LimitTo method, you can specify the max number of metadata record to return. This is especially useful when querying a dataset containing thousands of metadata records. Fetching to much metadata at once can impact performance.

    • When not set, the default value is set to the maximum value of an integer

    Combine filters

    
    public async Task QueryingMetadataAdvanced(IMetadataRepository metadataRepository, string[] rootKeysToQuery, InstanceId[] ownerIdsToConsider, IEnumerable<string> pathToKey, string expectedValue)
    {
        MatchCollection result = await metadataRepository.Query()
            .Select(rootKeysToQuery)
            .IncludedIn(ownerIdsToConsider)
            .WhereKeyEquals(pathToKey, expectedValue)
            .ExecuteAsync();
    }
    
    

    You can use any combination of the filters described above to build advanced queries and apply multiple filters at once.

    Use the result

    MatchCollection

    
    public async Task UsingTheMatchCollectionReturnedFromAQuery(IMetadataRepository metadataRepository, InstanceId id)
    {
        MatchCollection result = await metadataRepository.Query().ExecuteAsync();
        IEnumerable<InstanceId> ids = result.Keys;
        IEnumerable<MetadataObject> metadataObjects = result.Values;
        MetadataObject metadataObject = result[id];
    }
    
    

    Since MatchCollection is a ReadOnlyDictionnary, you can use your usual dictionaries method on it to get the data you want. For example, you can:

    • Use the property Keys to fetch all the contained OwnerId
    • Use the property Values to fetch all the contained MetadataObject
    • Use the square bracket operator to fetch a specific MetadataObject associated to an OwnerId

    MetadataObjects and MetadataValues

    The Metadata is always returned as a MetadataObject as it always is a valid JSON object at the root. MetadataObject extends MetadataContainer that is also extended by MetadataValue and MetadataArray. You can use a MetadataObject as a ReadOnlyDictionnary and access any valid JSON root objects, values or arrays by using the square bracket operator. When trying to read a value you can either use ToString() or ToNumber() depending on the underlying type.

    Use helper methods

    Getting all keys in the dataset

    
    public async Task QueryingAllRootKeys(IMetadataRepository metadataRepository)
    {
        // The result will contain all the root keys in the dataset
        IEnumerable<string> result = await metadataRepository.GetAllKeysAsync();
    }
    
    

    By using the GetAllKeysAsync method, you can retrieve all the root keys that are present in the dataset.

    Note

    This method can have lower performance if the dataset contains too much content.

    Getting all owner ids in the dataset

    
    public async Task QueryingAllIds(IMetadataRepository metadataRepository)
    {
        // The result will contain all the owner ids in the dataset
        IEnumerable<InstanceId> result = await metadataRepository.GetAllIdsAsync();
    }
    
    

    By using the GetAllIdsAsync method, you can retrieve all the owner ids present in the dataset.

    In This Article
    Back to top
    Copyright © 2024 Unity Technologies — Trademarks and terms of use
    • Legal
    • Privacy Policy
    • Cookie Policy
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)