androidquick-search

How to efficiently manage search suggestion using Android QSB?


I try to make a dictionary using Quick Search Box in Android. As shown in the SearchableDictionary tutorial, it loads all (999 definitions)data and uses them as matches to the input text to get the search suggestion. in my case, I have 26963 rows of data that need to be suggest while user input a word on QSB. therefore, I want to grab the char data one by one from the QSB, so that it will be efficiently load necessary suggestion. how can i do this?

here's the code i use...

bringit(200);
        if (Intent.ACTION_VIEW.equals(intent.getAction())) {
            // from click on search results
            //Dictionary.getInstance().ensureLoaded(getResources());
            String word = intent.getDataString();
            //if(word.length() > 3){bringit(10);}
            Dictionary.Word theWord = Dictionary.getMatches(word).get(0);
            launchWord(theWord);
            finish();
        } else if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            String query = intent.getStringExtra(SearchManager.QUERY);
            //SearchManager.
            //String bb = 
            mTextView.setText(getString(R.string.search_results, query));
            WordAdapter wordAdapter = new WordAdapter(Dictionary.getMatches(query));
            //letsCount(query);
            mList.setAdapter(wordAdapter);
            mList.setOnItemClickListener(wordAdapter);
        }

        Log.d("dict", intent.toString());
        if (intent.getExtras() != null) {
            Log.d("dict", intent.getExtras().keySet().toString());
        }
    }



    private void letsCount(String query) {
        // TODO Auto-generated method stub
        for(int i=0; i<query.length(); i++){
            definite[i] = query.charAt(i);
        }
    }



    public void bringit(int sum) {
        // TODO Auto-generated method stub
        String[] ss = new String[10];

        Log.d("dict", "loading words");

        for(int i=1; i<=sum; i++){
            KamusDbAdapter a = new KamusDbAdapter(getApplicationContext());
            a.open(); 
            Cursor x = a.quick(String.valueOf(i));startManagingCursor(x);
            if(x.moveToFirst()){
                ss[0] = x.getString(1);
                ss[1] = x.getString(2);
            }
            Dictionary.addWord(ss[0].trim(), ss[1].trim());
            Log.v("Debug",ss[0]+" "+ss[1]);
            //onStop();
        }
    }

I use SQLite to collect data. and the other code is just same as the tutorial...


Solution

  • Retrieving a cursor is generally slow. You only want to retrieve one cursor which contains all the matching results.

    You should perform the searching using SQL rather than fetching everything. A FULL_TEXT search is usually fastest for text matching, it is however slightly more complicated to implement than a simple LIKE, but I highly recommend you give it a try.

    So you want to execute an SQL statement like: SELECT * FROM my_table WHERE subject_column MATCH 'something'

    See SQLite FTS Extension for more information. You can also use wild-cards to match part of a word.

    In terms of search suggestions there is really no point returning more than around ~100 results since generally no users ever bother to scroll down that far, so you can further speed things up by adding a LIMIT 0, 100 to the end of your SQL statement.

    If possible only start getting cursors once the user has entered more than X number of characters (usually 3 but in you're case this may not be appropriate). That way you're not performing searches that could potentially match thousands of items.

    You seem to be leaving lots of cursors open until the application closes them even though you don't actually need them anymore: instead of calling startManagingCursor just make sure to call x.close() after your if (x.moveToFirst()) { ... } - this will free up memory faster.

    On an unrelated note: please don't name your variables and methods things like ss or bringIt() as it makes code hard to read -- what is ss and what does bringIt() bring exactly?