如何在elasticsearch中存储嵌套字段
how to store nested fields in elasticsearch
我正在使用 Java 高级 REST 客户端。这是 link to its documentation
我已经创建了一个客户端。
trait HighLevelRestClient {
def elasticSearchClient(): RestHighLevelClient = {
new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", ElasticSearchPort, "http")))
}
}
在索引数据时,嵌套字段被存储为字符串。以下代码解释了如何创建索引:
val indexRequest = new IndexRequest("my-index", "test-type").source(
"person", person,
"date", DateTime.now()
)
其中,人是个案class,表示为:
Person(personId: String, name: String, address: Address)
而Address本身就是一个caseclass,表示为:
Address(city: String, zip: Int)
我的应用程序要求将人员存储为键值对,以便可以搜索它的字段。但是,当我使用上面的代码时,它被存储为字符串。
{
"person" : "Person(my-id, my-name, Address(my-city, zip-value))",
"date" : "2017-12-12"
}
所需的结构是:
{
"person" : {
"personId" : "my-id",
"name" : "person-name",
"address": {
"city" : "city-name",
"zip" : 12345
}
},
"date" : "2017-12-12"
}
我希望我已经很好地提出了这个问题。任何帮助,将不胜感激。谢谢!
你快到了。要实现您的目标,您需要:
- 将对象序列化到你这边JSON
- 指定请求的内容类型
其实是在Index API的页面中描述的。
一个方便的库将 case 类 序列化为 JSON 例如 json4s (you can see some examples of serialization here).
您的代码可能如下所示:
import org.apache.http.HttpHost
import org.elasticsearch.action.index.IndexRequest
import org.elasticsearch.client.{RestClient, RestHighLevelClient}
import org.elasticsearch.common.xcontent.XContentType
import org.joda.time.DateTime
import org.json4s.NoTypeHints
import org.json4s.jackson.Serialization
import org.json4s.jackson.Serialization.write
case class Address(city: String, zip: Int)
case class Person(personId: String, name: String, address: Address)
case class Doc(person: Person, date: String)
object HighClient {
def main(args: Array[String]): Unit = {
val client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9206, "http")))
implicit val formats = Serialization.formats(NoTypeHints)
val doc = Doc(
Person("blah1", "Peter Parker", Address("New-York", 33755)),
DateTime.now().toString
)
val indexRequest = new IndexRequest("my-index", "test-type").source(
write(doc), XContentType.JSON
)
client.index(indexRequest)
client.close()
}
}
请注意,在这种情况下:
new IndexRequest("my-index", "test-type").source(
write(doc), XContentType.JSON
)
将使用此函数:public IndexRequest source(String source, XContentType xContentType)
而你的情况是:
new IndexRequest("my-index", "test-type").source(
"person", person,
"date", DateTime.now()
)
它将调用 public IndexRequest source(Object... source)
。
希望对您有所帮助!
我正在使用 Java 高级 REST 客户端。这是 link to its documentation
我已经创建了一个客户端。
trait HighLevelRestClient {
def elasticSearchClient(): RestHighLevelClient = {
new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", ElasticSearchPort, "http")))
}
}
在索引数据时,嵌套字段被存储为字符串。以下代码解释了如何创建索引:
val indexRequest = new IndexRequest("my-index", "test-type").source(
"person", person,
"date", DateTime.now()
)
其中,人是个案class,表示为:
Person(personId: String, name: String, address: Address)
而Address本身就是一个caseclass,表示为:
Address(city: String, zip: Int)
我的应用程序要求将人员存储为键值对,以便可以搜索它的字段。但是,当我使用上面的代码时,它被存储为字符串。
{
"person" : "Person(my-id, my-name, Address(my-city, zip-value))",
"date" : "2017-12-12"
}
所需的结构是:
{
"person" : {
"personId" : "my-id",
"name" : "person-name",
"address": {
"city" : "city-name",
"zip" : 12345
}
},
"date" : "2017-12-12"
}
我希望我已经很好地提出了这个问题。任何帮助,将不胜感激。谢谢!
你快到了。要实现您的目标,您需要:
- 将对象序列化到你这边JSON
- 指定请求的内容类型
其实是在Index API的页面中描述的。
一个方便的库将 case 类 序列化为 JSON 例如 json4s (you can see some examples of serialization here).
您的代码可能如下所示:
import org.apache.http.HttpHost
import org.elasticsearch.action.index.IndexRequest
import org.elasticsearch.client.{RestClient, RestHighLevelClient}
import org.elasticsearch.common.xcontent.XContentType
import org.joda.time.DateTime
import org.json4s.NoTypeHints
import org.json4s.jackson.Serialization
import org.json4s.jackson.Serialization.write
case class Address(city: String, zip: Int)
case class Person(personId: String, name: String, address: Address)
case class Doc(person: Person, date: String)
object HighClient {
def main(args: Array[String]): Unit = {
val client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9206, "http")))
implicit val formats = Serialization.formats(NoTypeHints)
val doc = Doc(
Person("blah1", "Peter Parker", Address("New-York", 33755)),
DateTime.now().toString
)
val indexRequest = new IndexRequest("my-index", "test-type").source(
write(doc), XContentType.JSON
)
client.index(indexRequest)
client.close()
}
}
请注意,在这种情况下:
new IndexRequest("my-index", "test-type").source(
write(doc), XContentType.JSON
)
将使用此函数:public IndexRequest source(String source, XContentType xContentType)
而你的情况是:
new IndexRequest("my-index", "test-type").source(
"person", person,
"date", DateTime.now()
)
它将调用 public IndexRequest source(Object... source)
。
希望对您有所帮助!