Getting zero results in search using elastic4s

2019-07-14 06:11发布

问题:

This is a small code I am using to do a simple search:

import com.sksamuel.elastic4s.{ElasticsearchClientUri, ElasticClient}
import com.sksamuel.elastic4s.ElasticDsl._
import org.elasticsearch.common.settings.ImmutableSettings

object Main3 extends App {
  val uri = ElasticsearchClientUri("elasticsearch://localhost:9300")
  val settings = ImmutableSettings.settingsBuilder().put("cluster.name", "elasticsearch").build()
  val client = ElasticClient.remote(settings, uri)
  if (client.exists("bands").await.isExists()) {
    println("Index already exists!")
    val num = readLine("Want to delete the index? ")
    if (num == "y") {
      client.execute {deleteIndex("bands")}.await
    } else {
      println("Leaving this here ...")
    }
  } else {
    println("Creating the index!")
    client.execute(create index "bands").await
    client.execute(index into "bands/artists" fields "name"->"coldplay").await
    val resp = client.execute(search in "bands/artists" query "coldplay").await
    println(resp)
  }
  client.close()
}

This is result that I get:

Connected to the target VM, address: '127.0.0.1:51872', transport: 'socket'
log4j:WARN No appenders could be found for logger (org.elasticsearch.plugins).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Creating the index!
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 0,
    "max_score" : null,
    "hits" : [ ]
  }
}
Disconnected from the target VM, address: '127.0.0.1:51872', transport: 'socket'

Process finished with exit code 0

Creation of an index and adding document to this index is running fine but a simple search query is giving no result. I even checked this on Sense.

GET bands/artists/_search
{
  "query": {
    "match": {
      "name": "coldplay"
    }
  }
}

gives

{
   "took": 4,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 0.30685282,
      "hits": [
         {
            "_index": "bands",
            "_type": "artists",
            "_id": "AU21OYO9w-qZq8hmdTOl",
            "_score": 0.30685282,
            "_source": {
               "name": "coldplay"
            }
         }
      ]
   }
}

How to solve this issue?

回答1:

I suspect what is happening is that you are doing the search straight after the index operation in your code. However in elasticsearch documents are not ready for search immediately. See refresh interval setting here. (So when you use the rest client, you are waiting a few seconds by virtue of the fact you have to manually flick between tabs, etc).

You could test this quickly by putting a Thread.sleep(3000) after the index. If that confirms it then works, then you need to think about how you want to write your program.

Normally you just index, and when the data is available, then its available. This is called eventual consistency. In the meantime (seconds) users might not have it available to search. That's usually not a problem.

If it IS a problem, then you will have to do some tricks like we do in the unit tests of elastic4s where you keep 'count'ing until you get back the right number of documents.

Finally, you can also manually 'refresh' the index to speed things up, by calling

client.execute {
  refresh index "indexname"
}

But that's usually only used when you turn off the automatic refreshing for bulk inserts.