int main(int argc, char *argv[]) { // Initialize the library. lucy_bootstrap_parcel(); if (argc != 2) { S_usage_and_exit(argv[0]); } const char *query_c = argv[1]; printf("Searching for: %s\n\n", query_c); String *folder = Str_newf("%s", path_to_index); String *language = Str_newf("en"); Simple *lucy = Simple_new((Obj*)folder, language); String *query_str = Str_newf("%s", query_c); Simple_Search(lucy, query_str, 0, 10); String *title_str = Str_newf("title"); String *url_str = Str_newf("url"); HitDoc *hit; int i = 1; // Loop over search results. while (NULL != (hit = Simple_Next(lucy))) { String *title = (String*)HitDoc_Extract(hit, title_str); char *title_c = Str_To_Utf8(title); String *url = (String*)HitDoc_Extract(hit, url_str); char *url_c = Str_To_Utf8(url); printf("Result %d: %s (%s)\n", i, title_c, url_c); free(url_c); free(title_c); DECREF(url); DECREF(title); DECREF(hit); i++; } DECREF(url_str); DECREF(title_str); DECREF(query_str); DECREF(lucy); DECREF(language); DECREF(folder); return 0; }
static void S_search(IndexSearcher *searcher, const char *query) { printf("Searching for: %s\n", query); // Execute search query. String *query_str = Str_new_from_utf8(query, strlen(query)); Hits *hits = IxSearcher_Hits(searcher, (Obj*)query_str, 0, 10, NULL); String *field_str = Str_newf("title"); HitDoc *hit; int i = 1; // Loop over search results. while (NULL != (hit = Hits_Next(hits))) { String *value_str = (String*)HitDoc_Extract(hit, field_str); char *value = Str_To_Utf8(value_str); printf("Result %d: %s\n", i, value); free(value); DECREF(value_str); DECREF(hit); i++; } printf("\n"); DECREF(query_str); DECREF(hits); DECREF(field_str); }
String* Highlighter_Create_Excerpt_IMP(Highlighter *self, HitDoc *hit_doc) { HighlighterIVARS *const ivars = Highlighter_IVARS(self); String *field_val = (String*)HitDoc_Extract(hit_doc, ivars->field); String *retval; if (!field_val || !Obj_Is_A((Obj*)field_val, STRING)) { retval = NULL; } else if (!Str_Get_Size(field_val)) { // Empty string yields empty string. retval = Str_new_from_trusted_utf8("", 0); } else { DocVector *doc_vec = Searcher_Fetch_Doc_Vec(ivars->searcher, HitDoc_Get_Doc_ID(hit_doc)); VArray *maybe_spans = Compiler_Highlight_Spans(ivars->compiler, ivars->searcher, doc_vec, ivars->field); VArray *score_spans = maybe_spans ? maybe_spans : VA_new(0); VA_Sort(score_spans, NULL, NULL); HeatMap *heat_map = HeatMap_new(score_spans, (ivars->excerpt_length * 2) / 3); int32_t top; String *raw_excerpt = Highlighter_Raw_Excerpt(self, field_val, &top, heat_map); String *highlighted = Highlighter_Highlight_Excerpt(self, score_spans, raw_excerpt, top); DECREF(raw_excerpt); DECREF(heat_map); DECREF(score_spans); DECREF(doc_vec); retval = highlighted; } DECREF(field_val); return retval; }
static void test_simple(TestBatchRunner *runner) { RAMFolder *folder = RAMFolder_new(NULL); String *language = SSTR_WRAP_UTF8("en", 2); Simple *lucy = Simple_new((Obj*)folder, language); String *food_field = SSTR_WRAP_UTF8("food", 4); { Doc *doc = Doc_new(NULL, 0); String *value = SSTR_WRAP_UTF8("creamed corn", 12); Doc_Store(doc, food_field, (Obj*)value); Simple_Add_Doc(lucy, doc); DECREF(doc); String *query = SSTR_WRAP_UTF8("creamed", 7); uint32_t num_results = Simple_Search(lucy, query, 0, 10); TEST_INT_EQ(runner, num_results, 1, "Search works right after add"); } { Doc *doc = Doc_new(NULL, 0); String *value = SSTR_WRAP_UTF8("creamed spinach", 15); Doc_Store(doc, food_field, (Obj*)value); Simple_Add_Doc(lucy, doc); DECREF(doc); String *query = SSTR_WRAP_UTF8("creamed", 7); uint32_t num_results = Simple_Search(lucy, query, 0, 10); TEST_INT_EQ(runner, num_results, 2, "Search returns total hits"); } { Doc *doc = Doc_new(NULL, 0); String *value = SSTR_WRAP_UTF8("creamed broccoli", 16); Doc_Store(doc, food_field, (Obj*)value); Simple_Add_Doc(lucy, doc); DECREF(doc); DECREF(lucy); lucy = Simple_new((Obj*)folder, language); String *query = SSTR_WRAP_UTF8("cream", 5); uint32_t num_results = Simple_Search(lucy, query, 0, 10); TEST_INT_EQ(runner, num_results, 3, "commit upon destroy"); HitDoc *hit; while ((hit = Simple_Next(lucy)) != NULL) { String *food = (String*)HitDoc_Extract(hit, food_field); TEST_TRUE(runner, Str_Starts_With_Utf8(food, "cream", 5), "Next"); DECREF(food); DECREF(hit); } } { Doc *doc = Doc_new(NULL, 0); String *band_field = SSTR_WRAP_UTF8("band", 4); String *value = SSTR_WRAP_UTF8("Cream", 5); Doc_Store(doc, band_field, (Obj*)value); Simple_Add_Doc(lucy, doc); DECREF(doc); String *query = SSTR_WRAP_UTF8("cream", 5); uint32_t num_results = Simple_Search(lucy, query, 0, 10); TEST_INT_EQ(runner, num_results, 4, "Search uses correct EasyAnalyzer"); } DECREF(lucy); DECREF(folder); }