docstr: Natural language query over nodes that returns a dataframe of results sorted by relevance column "distance".
  
      If node data is not yet feature-encoded (and explicit edges are given),
      run automatic feature engineering:
      ::
  
          g2 = g.featurize(kind='nodes', X=['text_col_1', ..],
          min_words=0 # forces all named columns are textually encoded
          )
  
      If edges do not yet exist, generate them via
      ::
  
          g2 = g.umap(kind='nodes', X=['text_col_1', ..],
          min_words=0 # forces all named columns are textually encoded
          )
      
      If an index is not yet built, it is generated `g2.build_index()` on the fly at search time.
      Otherwise, can set `g2.build_index()` to build it ahead of time.
  
  Args:
      :query (str): natural language query.
      :cols (list or str, optional): if fuzzy=False, select which column to query.
                                      Defaults to None since fuzzy=True by defaul.
      :thresh (float, optional): distance threshold from query vector to returned results.
                                  Defaults to 5000, set large just in case,
                                  but could be as low as 10.
      :fuzzy (bool, optional): if True, uses embedding + annoy index for recall,
                                  otherwise does string matching over given `cols`
                                  Defaults to True.
      :top_n (int, optional): how many results to return. Defaults to 100.
  
  Returns:
      **pd.DataFrame, vector_encoding_of_query:**
      rank ordered dataframe of results matching query
  
      vector encoding of query via given transformer/ngrams model if fuzzy=True else None
docstr_tok: ["Natural","language","query","over","nodes","that","returns","a","dataframe","of","results","sorted","by","relevance","column","``","distance","''",".","If","node","data","is","not","yet","feature-encoded","(","and","explicit","edges","are","given",")",",","run","automatic","feature","engineering",":",":",":","g2","=","g.featurize","(","kind='nodes","'",",","X=","[","'text_col_1","'",",","..","]",",","min_words=0","#","forces","all","named","columns","are","textually","encoded",")","If","edges","do","not","yet","exist",",","generate","them","via",":",":","g2","=","g.umap","(","kind='nodes","'",",","X=","[","'text_col_1","'",",","..","]",",","min_words=0","#","forces","all","named","columns","are","textually","encoded",")","If","an","index","is","not","yet","built",",","it","is","generated","`","g2.build_index","(",")","`","on","the","fly","at","search","time",".","Otherwise",",","can","set","`","g2.build_index","(",")","`","to","build","it","ahead","of","time",".","Args",":",":","query","(","str",")",":","natural","language","query",".",":","cols","(","list","or","str",",","optional",")",":","if","fuzzy=False",",","select","which","column","to","query",".","Defaults","to","None","since","fuzzy=True","by","defaul",".",":","thresh","(","float",",","optional",")",":","distance","threshold","from","query","vector","to","returned","results",".","Defaults","to","5000",",","set","large","just","in","case",",","but","could","be","as","low","as","10.",":","fuzzy","(","bool",",","optional",")",":","if","True",",","uses","embedding","+","annoy","index","for","recall",",","otherwise","does","string","matching","over","given","`","cols","`","Defaults","to","True",".",":","top_n","(","int",",","optional",")",":","how","many","results","to","return",".","Defaults","to","100",".","Returns",":","*","*","pd.DataFrame",",","vector_encoding_of_query",":","*","*","rank","ordered","dataframe","of","results","matching","query","vector","encoding","of","query","via","given","transformer\/ngrams","model","if","fuzzy=True","else","None"]
code: def search(
      self,
      query: str,
      cols=None,
      thresh: float = 5000,
      fuzzy: bool = True,
      top_n: int = 10,
  ):
      """Natural language query over nodes that returns a dataframe of results sorted by relevance column "distance".
  
          If node data is not yet feature-encoded (and explicit edges are given),
          run automatic feature engineering:
          ::
  
              g2 = g.featurize(kind='nodes', X=['text_col_1', ..],
              min_words=0 # forces all named columns are textually encoded
              )
  
          If edges do not yet exist, generate them via
          ::
  
              g2 = g.umap(kind='nodes', X=['text_col_1', ..],
              min_words=0 # forces all named columns are textually encoded
              )
  
          If an index is not yet built, it is generated `g2.build_index()` on the fly at search time.
          Otherwise, can set `g2.build_index()` to build it ahead of time.
  
      Args:
          :query (str): natural language query.
          :cols (list or str, optional): if fuzzy=False, select which column to query.
                                          Defaults to None since fuzzy=True by defaul.
          :thresh (float, optional): distance threshold from query vector to returned results.
                                      Defaults to 5000, set large just in case,
                                      but could be as low as 10.
          :fuzzy (bool, optional): if True, uses embedding + annoy index for recall,
                                      otherwise does string matching over given `cols`
                                      Defaults to True.
          :top_n (int, optional): how many results to return. Defaults to 100.
  
      Returns:
          **pd.DataFrame, vector_encoding_of_query:**
          rank ordered dataframe of results matching query
  
          vector encoding of query via given transformer/ngrams model if fuzzy=True else None
      """
      if not fuzzy:
          if cols is None:
              logger.error(
                  f"Columns to search for `{query}` \
                               need to be given when fuzzy=False, found {cols}"
              )
  
          logger.info(f"-- Word Match: [[ {query} ]]")
          return (
              pd.concat(
                  [
                      search_to_df(
                          query, col, self._nodes, as_string=True
                      )
                      for col in cols
                  ]
              ),
              None,
          )
      else:
          logger.info(f"-- Search: [[ {query} ]]")
          return self._query(query, thresh=thresh, top_n=top_n)
  
file_path: pygraphistry/graphistry/text_utils.py
imports: import pandas
  from .feature_utils import FeatureMixin
  from .ai_utils import search_to_df, FaissVectorSearch
  from .constants import WEIGHT, DISTANCE
  from logging import getLogger
  from typing import TYPE_CHECKING
label_desc: Use image node_id 7 for calling the SearchToGraphMixin obj's underlying member method code with example usage: obj.search(query, cols, thresh, fuzzy, top_n) and returns: pd,  None, self