+ v8::String::Utf8Value query(args[0]);
+ v8::String::Utf8Value optType(args[3]);
+ v8::Local<v8::Array> optArgsTuple;
+ if (args[4]->IsArray())
+ optArgsTuple = args[4].As<v8::Array>();
+ unsigned long startdoc = args[1]->IntegerValue();
+ unsigned long len = args[2]->IntegerValue();
+ IndexObject* Index = node::ObjectWrap::Unwrap<IndexObject>(args.Holder());
+ struct index_result* result;
+ unsigned int results;
+ double/*unsigned long int*/ total_results;
+ int est;
+ unsigned int accumulator_limit = args[5]->Uint32Value();
+ int opts = INDEX_SEARCH_NOOPT;
+ struct index_search_opt opt;
+
+ opt.u.okapi_k3.k1 = 1.2;
+ opt.u.okapi_k3.k3 = 1e10;
+ opt.u.okapi_k3.b = 0.75;
+
+ if (
+ (result = (struct index_result*)malloc(sizeof(*result) * len)) == NULL
+ ) {
+ isolate->ThrowException(
+ v8::String::NewFromUtf8(isolate, "Unable to allocate results")
+ );
+ return;
+ }
+ if (args[3]->IsString()) {
+ if (strcmp(*optType, "COSINE") == 0) {
+ opts = INDEX_SEARCH_COSINE_RANK;
+ } else if (strcmp(*optType, "OKAPI") == 0) {
+ opts = INDEX_SEARCH_OKAPI_RANK;
+ } else if (strcmp(*optType, "OKAPI_K3") == 0) {
+ if (optArgsTuple.IsEmpty()) {
+ isolate->ThrowException(
+ v8::String::NewFromUtf8(isolate, "Must supply args to search type")
+ );
+ free(result);
+ return;
+ }
+ opts = INDEX_SEARCH_OKAPI_RANK;
+ opt.u.okapi_k3.k1 = optArgsTuple->Get(0)->IntegerValue();
+ opt.u.okapi_k3.k3 = optArgsTuple->Get(1)->IntegerValue();
+ opt.u.okapi_k3.b = optArgsTuple->Get(2)->IntegerValue();
+ } else if (strcmp(*optType, "HAWKAPI") == 0) {
+ if (optArgsTuple.IsEmpty()) {
+ isolate->ThrowException(
+ v8::String::NewFromUtf8(isolate, "Must supply args to search type")
+ );
+ free(result);
+ return;
+ }
+ opts = INDEX_SEARCH_HAWKAPI_RANK;
+ opt.u.hawkapi.alpha = optArgsTuple->Get(0)->IntegerValue();
+ opt.u.hawkapi.k3 = optArgsTuple->Get(1)->IntegerValue();
+ } else if (strcmp(*optType, "DIRICHLET") == 0) {
+ opts = INDEX_SEARCH_DIRICHLET_RANK;
+ if (optArgsTuple.IsEmpty() || optArgsTuple->Length() == 0)
+ opt.u.dirichlet.mu = 2500.0;
+ else
+ opt.u.dirichlet.mu = optArgsTuple->Get(0)->NumberValue();
+ } else {
+ isolate->ThrowException(
+ v8::String::NewFromUtf8(isolate, "Unknown search type")
+ );
+ free(result);
+ return;
+ }
+ }
+ if (accumulator_limit != 0) {
+ opts |= INDEX_SEARCH_ACCUMULATOR_LIMIT;
+ opt.accumulator_limit = accumulator_limit;
+ }
+#if 1 /* Nick */
+ opts |= INDEX_SEARCH_SUMMARY_TYPE;
+ opt.summary_type = INDEX_SUMMARISE_CAPITALISE;
+#endif
+ if (!index_search(Index->idx, *query, startdoc, len,
+ result, &results, &total_results, &est, opts, &opt)) {
+ char err_buf[1024];
+ snprintf(err_buf, 1024, "Unable to perform search for query '%s'; "
+ "system error is '%s'\n", *query, strerror(errno));
+ isolate->ThrowException(
+ v8::String::NewFromUtf8(isolate, err_buf)
+ );
+ free(result);
+ return;
+ }
+ args.GetReturnValue().Set(
+ index_results_to_object(isolate, result, results, total_results)
+ );
+ free(result);
+ return;
+}
+
+static v8::Local<v8::Object> index_result_to_object(
+ v8::Isolate* isolate,
+ struct index_result* result
+) {
+ v8::EscapableHandleScope handle_scope(isolate);
+ v8::Local<v8::Object> result_object = v8::Object::New(isolate);
+ result_object->Set(
+ v8::String::NewFromUtf8(isolate, "docno"),
+ v8::Integer::New(isolate, result->docno)
+ );
+ result_object->Set(
+ v8::String::NewFromUtf8(isolate, "score"),
+ v8::Number::New(isolate, result->score)
+ );
+ result_object->Set(
+ v8::String::NewFromUtf8(isolate, "summary"),
+ v8::String::NewFromUtf8(isolate, result->summary)
+ );
+ result_object->Set(
+ v8::String::NewFromUtf8(isolate, "title"),
+ v8::String::NewFromUtf8(isolate, result->title)
+ );
+ result_object->Set(
+ v8::String::NewFromUtf8(isolate, "auxiliary"),
+ v8::String::NewFromUtf8(isolate, result->auxilliary)
+ );
+ return handle_scope.Escape(result_object);
+}