2

我目前有以下代码。以下是使用elastic4s库设置本地elasticsearch实例

val essettings = Settings
  .settingsBuilder().put("cluster.name", "elasticsearch")
  .put("path.home", "/tmp/v").build()

ElasticsearchConnection.setInstance(ElasticClient.local(essettings))

val mockESItem1 = Map("title" -> "Worth It",
  "artist" -> "Fifth Harmony",
  "countries" -> Seq("AI", "CA", "IT", "AU", "GB", "IO", "IE", "GI", "US", "SH", "MS", "KY"),
  "thumbnails" -> Seq(Map("default" -> "http://cache.vevo.com/Content/VevoImages/video/WRONGVEVOPICTURE.jpg")),
  "videoId" -> "VEVOID1", 
  "videoType" -> "type", 
  "ytVideoId" -> "YTID1", 
  "features" -> Seq(),
  "duration" -> 230)

在这里,我正在创建一个新索引,然后在上面插入 mockES 项。

client.execute( create index "videos" shards 1 replicas 5 mappings(
  "video" as (
    "artist" typed StringType,
    "title" typed StringType,
    "countries" typed StringType,
    "thumbnails" typed ObjectType,
    "videoId" typed StringType,
    "videoType" typed StringType,
    "ytVideoId" typed StringType,
    "features" typed StringType,
    "duration" typed IntegerType
    )
  )
)

client.execute(
  bulk(
    index into "videos"/"video" id 1 fields mockESItem1
  )
).await

但是,如果我随后运行查询以在我的任何测试中找到该项目,类似于以下内容:

es.execute {
  search in "videos" / "video" limit 5 query bool {
    must(
      queryStringQuery("Worth It").field("title"),
      queryStringQuery("Fifth Harmony").field("artist").field("features"),
      matchQuery("videoType","type"),
      matchQuery("countries","US")
    )
  }
}.await

该程序因以下错误而中断:

org.elasticsearch.action.NoShardAvailableActionException: null
at org.elasticsearch.action.search.type.TransportSearchTypeAction$BaseAsyncAction.start(TransportSearchTypeAction.java:151) [elasticsearch-2.0.1.jar:2.0.1]
at org.elasticsearch.action.search.type.TransportSearchQueryThenFetchAction.doExecute(TransportSearchQueryThenFetchAction.java:64) [elasticsearch-2.0.1.jar:2.0.1]
at org.elasticsearch.action.search.type.TransportSearchQueryThenFetchAction.doExecute(TransportSearchQueryThenFetchAction.java:53) [elasticsearch-2.0.1.jar:2.0.1]
...
org.elasticsearch.action.search.SearchPhaseExecutionException: all shards failed
at org.elasticsearch.action.search.type.TransportSearchTypeAction$BaseAsyncAction.onFirstPhaseResult(TransportSearchTypeAction.java:228) ~[elasticsearch-2.0.1.jar:2.0.1]
at org.elasticsearch.action.search.type.TransportSearchTypeAction$BaseAsyncAction.start(TransportSearchTypeAction.java:151) ~[elasticsearch-2.0.1.jar:2.0.1]
at org.elasticsearch.action.search.type.TransportSearchQueryThenFetchAction.doExecute(TransportSearchQueryThenFetchAction.java:64) ~[elasticsearch-2.0.1.jar:2.0.1]
at org.elasticsearch.action.search.type.TransportSearchQueryThenFetchAction.doExecute(TransportSearchQueryThenFetchAction.java:53) ~[elasticsearch-2.0.1.jar:2.0.1]

几天来,我一直试图断断续续地寻找解决此问题的方法,但找不到任何可以帮助我解决此问题的方法,因此现在查看 SE 上是否有人遇到过类似问题并发现一个修复。

更新

我已经重写了我所拥有的,所以这是一个更简单的例子,因为以前我自己的代码中仍然有几个类我正在使用。

import com.sksamuel.elastic4s.ElasticClient
import com.sksamuel.elastic4s.ElasticDsl._
import com.sksamuel.elastic4s.mappings.FieldType.{IntegerType, ObjectType, StringType}
import org.elasticsearch.action.delete.DeleteRequest
import org.elasticsearch.common.settings.Settings
import org.scalatest._
class ESTest extends FlatSpec with Matchers {
  val essettings = Settings
    .settingsBuilder().put("cluster.name", "elasticsearch")
    .put("path.home", "/tmp/v").build()

  val client = ElasticClient.local(essettings)

  val mockESItem1 = Map("title" -> "Worth It",
    "artist" -> "Fifth Harmony",
    "countries" -> Seq("AI", "CA", "IT", "AU", "GB", "IO", "IE", "GI", "US", "SH", "MS", "KY"),
    "thumbnails" -> Seq(Map("default" -> "http://cache.vevo.com/Content/VevoImages/video/WRONGVEVOPICTURE.jpg")),
    "videoId" -> "VEVOID1",
    "videoType" -> "type",
    "ytVideoId" -> "YTID1",
    "features" -> Seq(),
    "duration" -> 230)

  client.execute(create index "videos" shards 1 replicas 5 mappings (
    "video" as(
      "artist" typed StringType,
      "title" typed StringType,
      "countries" typed StringType,
      "thumbnails" typed ObjectType,
      "videoId" typed StringType,
      "videoType" typed StringType,
      "ytVideoId" typed StringType,
      "features" typed StringType,
      "duration" typed IntegerType
      )
    )
  ).await


  val exists = client.execute {
    index exists "videos"
  }.await.isExists

  println(exists)
  println(mockESItem1.get("videoId").get)

  client.execute(
    index into "videos" / "video" id mockESItem1.get("videoId").get fields mockESItem1
  ).await
  println("hi")

  val resp = client.execute {
    search in "videos" / "video" limit 5 query bool {
      must(
        matchQuery("videoType", "type"),
        matchQuery("countries", "US")
      )
    }
  }.await

  println(resp.hits.head.sourceAsString)
  client.client.delete(new DeleteRequest("videos"))
  client.close
}

目前,如果您运行它,它将无法执行批量插入,然后NoShardAvailableActionException在“测试”尝试运行搜索时收到。这可能是由specs2引起的问题吗?

4

2 回答 2

0

我遇到了类似的问题:当我在内存中的 Elasticsearch 节点上进行测试时,随后的测试运行失败并出现 NoShardAvailableActionException。当我意识到这只发生在测试运行 2 次或更多次时,我的解决方案是删除旧索引。大致上,我做了:

if (testsDoRunInInternalMode()) {
  client.admin().indices().delete(new DeleteIndexRequest(myIndex)).actionGet();
}

也许这有帮助。

于 2016-05-03T13:22:28.650 回答
0

这适用于 1.7.4(如果使用 2.0+ 将 ImmutableSettings 更改为 Settings):

object Test extends App {

  import ElasticDsl._

  val essettings = ImmutableSettings
    .settingsBuilder().put("cluster.name", "elasticsearch")
    .put("path.home", "/tmp/v").build()

  val client = ElasticClient.local(essettings)

  val mockESItem1 = Map("title" -> "Worth It",
    "artist" -> "Fifth Harmony",
    "countries" -> Seq("AI", "CA", "IT", "AU", "GB", "IO", "IE", "GI", "US", "SH", "MS", "KY"),
    "thumbnails" -> Seq(Map("default" -> "http://cache.vevo.com/Content/VevoImages/video/WRONGVEVOPICTURE.jpg")),
    "videoId" -> "VEVOID1",
    "videoType" -> "type",
    "ytVideoId" -> "YTID1",
    "features" -> Seq(),
    "duration" -> 230)

  client.execute(create index "videos" shards 1 replicas 5 mappings (
    "video" as(
      "artist" typed StringType,
      "title" typed StringType,
      "countries" typed StringType,
      "thumbnails" typed ObjectType,
      "videoId" typed StringType,
      "videoType" typed StringType,
      "ytVideoId" typed StringType,
      "features" typed StringType,
      "duration" typed IntegerType
      )
    )
  )

  client.execute(
    bulk(
      index into "videos" / "video" id 1 fields mockESItem1
    )
  ).await

  val resp = client.execute {
    search in "videos" / "video" limit 5 query bool {
      must(
        matchQuery("videoType", "type"),
        matchQuery("countries", "US")
      )
    }
  }.await

  println(resp.hits.head.sourceAsString)
  sys.exit(0)
}

由于这是您的代码,其中添加了您错过的部分,因此我只能假设您的错误出现在您未显示的某些代码中(例如ElasticsearchConnection)。我还稍微调整了您的查询。

于 2015-12-22T07:59:39.553 回答