Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Feature Request Better string field indexing in Search

Discussion in 'Editor Workflows' started by Theta_, Oct 16, 2023.

  1. Theta_

    Theta_

    Joined:
    Jun 20, 2019
    Posts:
    6
    Hello,

    I tried to use Search filters to quickly find ScriptableObjects in my card game. For example with a request like this:

    t:CardData text:draw

    But it didn't work.

    Search seems to only index strings with 5 to 32 characters without any special characters (even spaces). Other strings seems to be indexed for exact matches only.

    It makes the tool way more limited that what I was expecting.

    Am I missing something? Would it be possible to improve string indexing/searching? Or are we supposed to write our own tools for stuff like this and only use Search for the most basic searches?
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    4,196
    t:CardData by itself brings up results?
    Not sure about text: perhaps this needs quotes or only looks for exact matches (possibly even case sensitive) so perhaps text:*draw* or text: Draw might work.
     
  3. Theta_

    Theta_

    Joined:
    Jun 20, 2019
    Posts:
    6
    Yes
    t:CardData
    works.
    t:CardData Text:"complete card text"
    also works with exact matches (but that's not very usefull).

    According to the doc,
    property:string
    search for partial matches and
    property=string
    search for exact matches.

    But, as I said, partial match seems to only work if the field value is a string with 5 to 32 characters without any special characters (I experimented a lot as it seemed random at first).

    In any other case, only exact matches are found.
     
  4. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    4,196
    Disallowing partial string match searches for strings less than a certain length is a common optimization, otherwise too many results could tax the GUI or other systems. Typically it‘s a minimum of 3 or 4 characters but depends on the software. I can imagine that this is the case here but I can‘t say for certain.
     
  5. Theta_

    Theta_

    Joined:
    Jun 20, 2019
    Posts:
    6
    No that's not the problem. The length limit is not on the search pattern but on the string field of the assets.

    For example if I create 4 cards:
    * 1) Text: "Draw 2 cards" (special characters)
    * 2) Text: "Draw2Cards"
    * 3) Text: "Draw" (less than 5 characters)
    * 4) Text: "Draw2cardsDraw2cardsDraw2cardsDraw2cards" (more than 32 characters)

    t:CardData Text:dra
    will find only 2
    t:CardData Text:draw
    will find 2 and 3 (because 3 is an exact match)
    t:CardData text:"Draw 2 Cards"
    will find 1 (exact matches still work with special characters)

    I think the reason behind this is the fact that all types are indexed as either string or number. This limitations make sense for the string representations of enums or colors for example. But not for most string fields.
     
    Last edited: Oct 17, 2023
  6. sebastienp_unity

    sebastienp_unity

    Unity Technologies

    Joined:
    Feb 16, 2018
    Posts:
    170
    Hi @Theta_

    you are right that the Search Index do not store complete string, only hashcode of string to be able to search as fast as possible. This is not problematic for most short strings. From memory we hash string results from 1 letter up to 32. I am surprised that in your case a string less than 5 characters. I will test this locally and see if I can repro.

    Which version of Unity are you using?

    Thanks for your feedback,

    Seb
     
  7. sebastienp_unity

    sebastienp_unity

    Unity Technologies

    Joined:
    Feb 16, 2018
    Posts:
    170
    Hi @Theta_ I repro your use cases. I will investigate this further and fix what can be fixed. Thanks for reporting.
     
  8. sebastienp_unity

    sebastienp_unity

    Unity Technologies

    Joined:
    Feb 16, 2018
    Posts:
    170
    Hi @Theta_

    I have fixed most of the issues you have reported. For the time being all string properties bigger dans 32 characters are only indexed exactly.

    That said, this is something you can modify in your project. You could create a custom indexer for your type of data (CadData) and specify how you want to index the properties. The following example should provide the functionality you are looking for:

    Code (CSharp):
    1. using UnityEditor.Search;
    2.  
    3. public class CardDescriptionIndexer
    4. {
    5.     [CustomObjectIndexer(typeof(CardData))]
    6.     static void IndexLongProperties(CustomObjectIndexerTarget target, ObjectIndexer indexer)
    7.     {
    8.         var card = target.target as CardData;
    9.         if (card == null)
    10.             return;
    11.  
    12.         // Note: we index the property under a different name (long_description) because the indexing system will override how indexing is done.
    13.         // This will be fixed shortly: all custom indexers will be ran after the default indexers.
    14.  
    15.         // Note: see https://docs.unity3d.com/2022.3/Documentation/ScriptReference/Search.ObjectIndexer.IndexPropertyComponents.html
    16.         indexer.IndexPropertyComponents(target.documentIndex, "long_description", card.cardDescription);
    17.     }
    18. }
    19.  
    Then running the query
    p: t:CardData long_description:draw

    would yield the 4 cardDatas from your example

    * 1) Text: "Draw 2 cards" (special characters)
    * 2) Text: "Draw2Cards"
    * 3) Text: "Draw" (less than 5 characters)
    * 4) Text: "Draw2cardsDraw2cardsDraw2cardsDraw2cards" (more than 32 characters)

    upload_2023-10-23_16-0-50.png
     
  9. Theta_

    Theta_

    Joined:
    Jun 20, 2019
    Posts:
    6
    Thank you for your time.

    I didn't know about CustomObjectIndexer. Your script does what I wanted to do.