# IQueryEngineFilter

> Interface for the QueryEngine filters.

## Definition

* **Type:** Interface
* **Namespace:** [UnityEditor.Search](/engine/6000.6/script-reference/unityeditor/search.md)
* **Assembly:** UnityEditor

```csharp
public interface IQueryEngineFilter
```

## Remarks

When you add a new filter on a [QueryEngine](/engine/6000.6/script-reference/unityeditor/search/queryengine1.md), you receive a filter object that implements the interface [IQueryEngineFilter](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter.md). You can modify this filter to override the global behaviors of the [QueryEngine](/engine/6000.6/script-reference/unityeditor/search/queryengine1.md). For example, you can add [type parsers](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/addtypeparser.md) or [operators](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/addoperator.md) that are specific to this filter.

## Examples

```csharp
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using UnityEditor;
using UnityEditor.Search;
using UnityEngine;

static class Example_IQueryEngineFilter
{
    static List<MyObjectType> s_Data;

    static QueryEngine<MyObjectType> SetupQueryEngine()
    {
        // Set up the query engine
        var queryEngine = new QueryEngine<MyObjectType>();

        // Add a filter for MyObjectType.position that supports equals and not equals
        queryEngine.AddFilter("p", myObj => myObj.position, new[] { "=", "!=" });

        #region add_filter_type_parser
        // Add a new type parser for Vector2 written as "[x, y]", but only for this filter.
        // This type parser will not affect other filters.
        queryEngine.TryGetFilter("p", out var filter);
        filter.AddTypeParser(s =>
        {
            // If the format requirement is not met, return a failure.
            if (!s.StartsWith("[") || !s.EndsWith("]"))
                return ParseResult<Vector2>.none;

            var trimmed = s.Trim('[', ']');
            var vectorTokens = trimmed.Split(',');
            var vectorValues = vectorTokens.Select(token => float.Parse(token, CultureInfo.InvariantCulture.NumberFormat)).ToList();
            if (vectorValues.Count != 2)
                return ParseResult<Vector2>.none;
            var vector = new Vector2(vectorValues[0], vectorValues[1]);

            // When the conversion succeeds, return a success.
            return new ParseResult<Vector2>(true, vector);
        });
        #endregion

        #region add_filter_operator_handlers
        // Override global operators with specific operator handlers for this filter
        filter.AddOperator("=").AddHandler((Vector2 ev, Vector2 fv) => ev == fv);
        filter.AddOperator("!=").AddHandler((Vector2 ev, Vector2 fv) => ev != fv);
        #endregion

        // Set up what data from objects of type MyObjectType will be matched against search words
        queryEngine.SetSearchDataCallback(myObj => new[] { myObj.id.ToString(), myObj.name });

        return queryEngine;
    }

    [MenuItem("Examples/IQueryEngineFilter/IQueryEngineFilter")]
    public static void RunExample()
    {
        s_Data = GenerateExampleData();
        var queryEngine = SetupQueryEngine();
        TestFiltering(queryEngine, s_Data);
    }

    static void TestFiltering(QueryEngine<MyObjectType> queryEngine, IEnumerable<MyObjectType> inputData)
    {
        var vec = new Vector2(1, 0);
        // Find objects that are at position [1, 0]
        var filteredData = FilterData("p=[1,0]", queryEngine, inputData);
        ValidateData(filteredData, s_Data.Where(myObj => myObj.position == vec));

        //Find objects that are not at position [1, 0]
        filteredData = FilterData("p!=[1,0]", queryEngine, inputData);
        ValidateData(filteredData, s_Data.Where(myObj => myObj.position != vec));
    }

    static IEnumerable<MyObjectType> FilterData(string inputQuery, QueryEngine<MyObjectType> queryEngine, IEnumerable<MyObjectType> inputData)
    {
        // Parse the query string into a query operation
        var query = queryEngine.ParseQuery(inputQuery);

        // If the query is not valid, print all errors and return an empty data set
        if (!query.valid)
        {
            foreach (var queryError in query.errors)
            {
                Debug.LogFormat(LogType.Error, LogOption.NoStacktrace, null, $"Error parsing input at {queryError.index}: {queryError.reason}");
            }

            return new List<MyObjectType>();
        }

        // Apply the query on a data set and get the filtered result.
        var filteredData = query.Apply(inputData);
        return filteredData;
    }

    static void ValidateData(IEnumerable<MyObjectType> filteredData, IEnumerable<MyObjectType> expectedData)
    {
        var filteredDataArray = filteredData.ToArray();
        var expectedDataArray = expectedData.ToArray();
        Debug.Assert(filteredDataArray.Length == expectedDataArray.Length, $"Filtered data should have {expectedDataArray.Length} elements.");
        if (filteredDataArray.Length != expectedDataArray.Length)
            return;

        for (var i = 0; i < expectedDataArray.Length; i++)
        {
            Debug.Assert(filteredDataArray[i] == expectedDataArray[i], $"{filteredDataArray[i]} should be equal to {expectedDataArray[i]}");
        }
    }

    static List<MyObjectType> GenerateExampleData()
    {
        var data = new List<MyObjectType>()
        {
            new MyObjectType { id = 0, name = "Test 1", position = new Vector2(0, 0), active = false },
            new MyObjectType { id = 1, name = "Test 2", position = new Vector2(0, 1), active = true },
            new MyObjectType { id = 2, name = "Test 3", position = new Vector2(1, 0), active = false },
            new MyObjectType { id = 3, name = "Test 4", position = new Vector2(1.2f, 0), active = false },
        };

        return data;
    }

    /// <summary>
    /// Custom type. This is the type of objects that will be searched by the QueryEngine.
    /// </summary>
    class MyObjectType
    {
        public int id { get; set; }
        public string name { get; set; }
        public Vector2 position { get; set; }
        public bool active { get; set; }

        public MyObjectType()
        {
            id = 0;
            name = "";
            position = Vector2.zero;
            active = false;
        }

        public override string ToString()
        {
            return $"({id}, {name}, ({position.x}, {position.y}), {active})";
        }
    }
}
```

## Properties

| Property                                                                                                                          | Description                                                                                                                              |
| --------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| [metaInfo](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/metainfo.md)                                     | Additional information specific to the filter.                                                                                           |
| [operators](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/operators.md)                                   | Collection of [QueryFilterOperators](/engine/6000.6/script-reference/unityeditor/search/queryfilteroperator.md) specific for the filter. |
| [overridesStringComparison](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/overridesstringcomparison.md)   | Indicates if the filter overrides the global string comparison options.                                                                  |
| [parameterType](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/parametertype.md)                           | The type of the constant parameter passed to the filter, if used.                                                                        |
| [regexToken](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/regextoken.md)                                 | The regular expression that matches the filter. Matches what precedes the operator in a filter (for example. "id" in "id>=2").           |
| [stringComparison](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/stringcomparison.md)                     | The string comparison options of the filter.                                                                                             |
| [supportedOperators](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/supportedoperators.md)                 | List of supported operators.                                                                                                             |
| [token](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/token.md)                                           | The identifier of the filter. Typically what precedes the operator in a filter (for example, "id" in "id>=2").                           |
| [type](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/type.md)                                             | The type of the data that is compared by the filter.                                                                                     |
| [usesParameter](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/usesparameter.md)                           | Indicates if the filter uses a parameter.                                                                                                |
| [usesRegularExpressionToken](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/usesregularexpressiontoken.md) | Indicates if the filter uses a regular expression token or not.                                                                          |
| [usesResolver](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/usesresolver.md)                             | Indicates if the filter uses a resolver function.                                                                                        |

## Methods

| Method                                                                                                                          | Description                                                                                                                                                       |
| ------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [AddOperator](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/addoperator.md)                             | Add a custom filter operator specific to the filter.                                                                                                              |
| [AddOrUpdateMetaInfo](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/addorupdatemetainfo.md)             | Add or update additional information specific to the filter.                                                                                                      |
| [AddTypeParser](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/addtypeparser.md)                         | Add a type parser specific to the filter.                                                                                                                         |
| [ClearMetaInfo](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/clearmetainfo.md)                         | Removes all additional information specific to the filter.                                                                                                        |
| [RemoveMetaInfo](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/removemetainfo.md)                       | Remove information on the filter.                                                                                                                                 |
| [RemoveOperator](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/removeoperator.md)                       | Remove a custom operator specific to the filter.                                                                                                                  |
| [SetNestedQueryTransformer](/engine/6000.6/script-reference/unityeditor/search/iqueryenginefilter/setnestedquerytransformer.md) | Sets the filter's nested query transformer function. This function takes the result of a nested query and extracts the necessary data to compare with the filter. |
