转换和索引自定义 JSON

如果您有希望索引的 JSON 文档,但不想将其转换为 Solr 的结构,则可以通过在更新请求中包含一些参数将其添加到 Solr。

这些参数提供有关如何将单个 JSON 文件拆分为多个 Solr 文档以及如何将字段映射到 Solr 模式的信息。可以使用配置参数将一个或多个有效 JSON 文档发送到 /update/json/docs 路径。

映射参数

这些参数允许您定义如何读取 JSON 文件以获得多个 Solr 文档。

split

可选

默认值:无

定义将输入 JSON 拆分为多个 Solr 文档的路径,如果您在单个 JSON 文件中有多个文档,则需要此路径。如果整个 JSON 构成单个 Solr 文档,则路径必须为“/”。

可以通过管道 (|) 分隔多个 split 路径来传递它们,例如:split=/|/foo|/foo/bar。如果一个路径是另一个路径的子路径,则它们会自动成为子文档。

f

必需

默认值:无

提供多值映射以将文档字段名称映射到 Solr 字段名称。参数的格式为 target-field-name:json-path,例如 f=first:/firstjson-path 是必需的。target-field-name 是 Solr 文档字段名称,是可选的。如果未指定,则会自动从输入 JSON 中派生。默认目标字段名称是字段的完全限定名称。

此处可以使用通配符,有关更多信息,请参阅下面的 使用通配符作为字段名称

mapUniqueKeyOnly

可选

默认值:false

当输入 JSON 中的字段在模式中不可用且未启用 无模式模式 时,此参数特别方便。这会将所有字段索引到默认搜索字段(使用 df 参数),并且只有 uniqueKey 字段映射到模式中的相应字段。如果输入 JSON 没有 uniqueKey 字段的值,则会为其生成一个 UUID。

df

可选

默认值:无

如果启用了 mapUniqueKeyOnly 标志,则更新处理程序需要一个字段来索引数据。这与其他处理程序用作默认搜索字段的字段相同。

srcField

可选

默认值:无

这是将 JSON 源存储到的字段的名称。这只能在 split=/ 时使用(即,您希望将 JSON 输入文件索引为单个 Solr 文档)。请注意,原子更新会导致字段与文档不同步。

echo

可选

默认值:false

仅用于调试目的。如果希望将文档作为响应返回,请将其设置为 true。不会索引任何内容。

例如,如果我们有一个包含两个文档的 JSON 文件,我们可以这样定义更新请求

V1 API

curl 'http://localhost:8983/solr/techproducts/update/json/docs'\
'?split=/exams'\
'&f=first:/first'\
'&f=last:/last'\
'&f=grade:/grade'\
'&f=subject:/exams/subject'\
'&f=test:/exams/test'\
'&f=marks:/exams/marks'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

V2 API 用户管理 / 单节点 Solr

curl 'http://localhost:8983/api/cores/techproducts/update/json/docs'\
'?split=/exams'\
'&f=first:/first'\
'&f=last:/last'\
'&f=grade:/grade'\
'&f=subject:/exams/subject'\
'&f=test:/exams/test'\
'&f=marks:/exams/marks'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

V2 API SolrCloud

curl 'http://localhost:8983/api/collections/techproducts/update/json/docs'\
'?split=/exams'\
'&f=first:/first'\
'&f=last:/last'\
'&f=grade:/grade'\
'&f=subject:/exams/subject'\
'&f=test:/exams/test'\
'&f=marks:/exams/marks'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

通过此请求,我们定义了“exams”包含多个文档。此外,我们还将输入文档中的多个字段映射到 Solr 字段。

更新请求完成后,以下两个文档将被添加到索引中

{
  "first":"John",
  "last":"Doe",
  "marks":90,
  "test":"term1",
  "subject":"Maths",
  "grade":8
}
{
  "first":"John",
  "last":"Doe",
  "marks":86,
  "test":"term1",
  "subject":"Biology",
  "grade":8
}

在前面的示例中,我们想要在 Solr 中使用的所有字段都与输入 JSON 中的名称相同。在这种情况下,我们可以通过仅指定 f 参数的 json-path 部分来简化请求,例如

V1 API

curl 'http://localhost:8983/solr/techproducts/update/json/docs'\
'?split=/exams'\
'&f=/first'\
'&f=/last'\
'&f=/grade'\
'&f=/exams/subject'\
'&f=/exams/test'\
'&f=/exams/marks'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

V2 API 用户管理 / 单节点 Solr

curl 'http://localhost:8983/api/cores/techproducts/update/json/docs'\
'?split=/exams'\
'&f=/first'\
'&f=/last'\
'&f=/grade'\
'&f=/exams/subject'\
'&f=/exams/test'\
'&f=/exams/marks'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

V2 API SolrCloud

curl 'http://localhost:8983/api/collections/techproducts/update/json/docs'\
'?split=/exams'\
'&f=/first'\
'&f=/last'\
'&f=/grade'\
'&f=/exams/subject'\
'&f=/exams/test'\
'&f=/exams/marks'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

在此示例中,我们只是命名了字段路径(例如 /exams/test)。Solr 将自动尝试将 JSON 输入中字段的内容添加到具有相同名称的索引中的字段。

如果字段在索引之前不存在于模式中,则文档将在索引期间被拒绝。因此,如果您没有使用无模式模式,则必须预先创建所有字段。但是,如果您在 无模式模式 中工作,则不存在的字段将根据 Solr 对字段类型的最佳猜测动态创建。

在多个请求中重用参数

您可以使用 Solr 的 请求参数 API 存储和重用参数。

假设我们想要定义参数以在 exams 字段处拆分文档,并映射其他几个字段。我们可以发出类似以下的 API 请求

V1 API

 curl http://localhost:8983/solr/techproducts/config/params -H 'Content-type:application/json' -d '{
 "set": {
   "my_params": {
     "split": "/exams",
     "f": ["first:/first","last:/last","grade:/grade","subject:/exams/subject","test:/exams/test"]
 }}}'

V2 API 用户管理 / 单节点 Solr

curl http://localhost:8983/api/cores/techproducts/config/params -H 'Content-type:application/json' -d '{
 "set": {
   "my_params": {
     "split": "/exams",
     "f": ["first:/first","last:/last","grade:/grade","subject:/exams/subject","test:/exams/test"]
 }}}'

V2 API SolrCloud

curl http://localhost:8983/api/collections/techproducts/config/params -H 'Content-type:application/json' -d '{
 "set": {
   "my_params": {
     "split": "/exams",
     "f": ["first:/first","last:/last","grade:/grade","subject:/exams/subject","test:/exams/test"]
 }}}'

当我们发送文档时,我们将使用 useParams 参数以及我们定义的参数集的名称

V1 API

curl 'http://localhost:8983/solr/techproducts/update/json/docs?useParams=my_params' -H 'Content-type:application/json' -d '{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [{
      "subject": "Maths",
      "test": "term1",
      "marks": 90
    },
    {
      "subject": "Biology",
      "test": "term1",
      "marks": 86
    }
  ]
}'

V2 API 用户管理 / 单节点 Solr

curl 'http://localhost:8983/api/cores/techproducts/update/json?useParams=my_params' -H 'Content-type:application/json' -d '{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [{
      "subject": "Maths",
      "test": "term1",
      "marks": 90
    },
    {
      "subject": "Biology",
      "test": "term1",
      "marks": 86
    }
  ]
}'

V2 API SolrCloud

curl 'http://localhost:8983/api/collections/techproducts/update/json?useParams=my_params' -H 'Content-type:application/json' -d '{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [{
      "subject": "Maths",
      "test": "term1",
      "marks": 90
    },
    {
      "subject": "Biology",
      "test": "term1",
      "marks": 86
    }
  ]
}'

使用通配符表示字段名称

无需显式指定所有字段名称,可以使用通配符自动映射字段。

有两个限制:通配符只能用于 json-path 的末尾,并且拆分路径不能使用通配符。

单个星号 * 仅映射到直接子级,双星号 ** 递归映射到所有后代。以下是示例通配符路径映射

  • f=$FQN:/**:将所有字段映射到 JSON 字段的完全限定名称 ($FQN)。完全限定名称是通过使用句点 (.) 作为分隔符连接层次结构中的所有键来获得的。如果未指定任何 f 路径映射,则这是默认行为。

  • f=/docs/*:映射 docs 下的所有字段,名称与 JSON 中给出的名称相同

  • f=/docs/**:映射 docs 下的所有字段及其子级,名称与 JSON 中给出的名称相同

  • f=searchField:/docs/*:将 docs 下的所有字段映射到名为“searchField”的单个字段

  • f=searchField:/docs/**:将 docs 下的所有字段及其子级映射到 searchField

使用通配符,我们可以进一步简化前面的示例,如下所示

V1 API

curl 'http://localhost:8983/solr/techproducts/update/json/docs'\
'?split=/exams'\
'&f=/**'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

V2 API 用户管理 / 单节点 Solr

curl 'http://localhost:8983/api/cores/techproducts/update/json'\
'?split=/exams'\
'&f=/**'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

V2 API SolrCloud

curl 'http://localhost:8983/api/collections/techproducts/update/json'\
'?split=/exams'\
'&f=/**'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

因为我们希望字段在索引时使用 JSON 输入中找到的字段名称,所以 f=/** 中的双通配符将映射所有字段及其后代到 Solr 中的相同字段。

也可以将所有值发送到单个字段并对该字段进行全文搜索。这是一种在不担心字段和模式的情况下盲目索引和查询 JSON 文档的好方法。

V1 API

curl 'http://localhost:8983/solr/techproducts/update/json/docs'\
'?split=/'\
'&f=txt:/**'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

V2 API 用户管理 / 单节点 Solr

curl 'http://localhost:8983/api/cores/techproducts/update/json'\
'?split=/'\
'&f=txt:/**'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

V2 API SolrCloud

curl 'http://localhost:8983/api/collections/techproducts/update/json'\
'?split=/'\
'&f=txt:/**'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

在上面的示例中,我们说所有字段都应该添加到名为“txt”的 Solr 字段中。这会将多个字段添加到单个字段中,因此您选择的任何字段都应该是多值字段。

默认行为是使用节点的完全限定名称 (FQN)。因此,如果我们没有定义任何字段映射,例如

V1 API

curl 'http://localhost:8983/solr/techproducts/update/json/docs?split=/exams'\
    -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

V2 API 用户管理 / 单节点 Solr

curl 'http://localhost:8983/api/cores/techproducts/update/json?split=/exams'\
    -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

V2 API SolrCloud

curl 'http://localhost:8983/api/collections/techproducts/update/json?split=/exams'\
    -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

索引的文档将以类似于以下字段的字段添加到索引中

{
  "first":"John",
  "last":"Doe",
  "grade":8,
  "exams.subject":"Maths",
  "exams.test":"term1",
  "exams.marks":90},
{
  "first":"John",
  "last":"Doe",
  "grade":8,
  "exams.subject":"Biology",
  "exams.test":"term1",
  "exams.marks":86}

单个有效负载中的多个文档

此功能支持 JSON Lines 格式 (.jsonl) 中的文档,该格式指定每行一个文档。

例如

V1 API

curl 'http://localhost:8983/solr/techproducts/update/json/docs' -H 'Content-type:application/json' -d '
{ "first":"Steve", "last":"Jobs", "grade":1, "subject":"Social Science", "test":"term1", "marks":90}
{ "first":"Steve", "last":"Woz", "grade":1, "subject":"Political Science", "test":"term1", "marks":86}'

V2 API 用户管理 / 单节点 Solr

curl 'http://localhost:8983/api/collections/techproducts/update/json' -H 'Content-type:application/json' -d '
{ "first":"Steve", "last":"Jobs", "grade":1, "subject":"Social Science", "test":"term1", "marks":90}
{ "first":"Steve", "last":"Woz", "grade":1, "subject":"Political Science", "test":"term1", "marks":86}'

V2 API SolrCloud

curl 'http://localhost:8983/api/collections/techproducts/update/json' -H 'Content-type:application/json' -d '
{ "first":"Steve", "last":"Jobs", "grade":1, "subject":"Social Science", "test":"term1", "marks":90}
{ "first":"Steve", "last":"Woz", "grade":1, "subject":"Political Science", "test":"term1", "marks":86}'

甚至是一个文档数组,例如

V1 API

curl 'http://localhost:8983/solr/techproducts/update/json/docs' -H 'Content-type:application/json' -d '[
{"first":"Steve", "last":"Jobs", "grade":1, "subject":"Computer Science", "test":"term1", "marks":90},
{"first":"Steve", "last":"Woz", "grade":1, "subject":"Calculus", "test":"term1", "marks":86}]'

V2 API 用户管理 / 单节点 Solr

curl 'http://localhost:8983/api/cores/techproducts/update/json' -H 'Content-type:application/json' -d '[
{"first":"Steve", "last":"Jobs", "grade":1, "subject":"Computer Science", "test":"term1", "marks":90},
{"first":"Steve", "last":"Woz", "grade":1, "subject":"Calculus", "test":"term1", "marks":86}]'

V2 API SolrCloud

curl 'http://localhost:8983/api/collections/techproducts/update/json' -H 'Content-type:application/json' -d '[
{"first":"Steve", "last":"Jobs", "grade":1, "subject":"Computer Science", "test":"term1", "marks":90},
{"first":"Steve", "last":"Woz", "grade":1, "subject":"Calculus", "test":"term1", "marks":86}]'

自定义 JSON 索引的提示

  1. 无模式模式:这会自动处理字段创建。字段猜测可能与您的预期不完全一致,但它有效。最好的做法是在无模式模式下设置本地服务器,索引几个示例文档,并在实际索引之前使用正确的字段类型在您的真实设置中创建这些字段

  2. 预先创建的模式:将您的文档发布到 /update/json/docs 端点,并使用 echo=true。这将为您提供需要创建的字段名称列表。在实际索引之前创建字段

  3. 没有模式,只有全文搜索:您需要做的就是对您的 JSON 进行全文搜索。将配置设置为“设置 JSON 默认值”部分中给出的配置。

设置 JSON 默认值

可以将任何 JSON 发送到 /update/json/docs 端点,组件的默认配置如下

<initParams path="/update/json/docs">
  <lst name="defaults">
    <!-- this ensures that the entire JSON doc will be stored verbatim into one field -->
    <str name="srcField">_src_</str>
    <!-- This means the uniqueKeyField will be extracted from the fields and
         all fields go into the 'df' field. In this config df is already configured to be 'text'
     -->
    <str name="mapUniqueKeyOnly">true</str>
    <!-- The default search field where all the values are indexed to -->
    <str name="df">text</str>
  </lst>
</initParams>

因此,如果未传递任何参数,则整个 JSON 文件将被索引到 _src_ 字段,并且输入 JSON 中的所有值都将转到名为 text 的字段。如果 uniqueKey 有值,则会存储该值,如果无法从输入 JSON 中获取值,则会创建一个 UUID 并用作 uniqueKey 字段值。

或者,使用请求参数功能设置这些参数,如前面“在多个请求中重用参数”部分所示。

V1 API

 curl http://localhost:8983/solr/techproducts/config/params -H 'Content-type:application/json' -d '{
"set": {
  "full_txt": {
    "srcField": "_src_",
    "mapUniqueKeyOnly" : true,
    "df": "text"
}}}'

V2 API 用户管理 / 单节点 Solr

 curl http://localhost:8983/api/cores/techproducts/config/params -H 'Content-type:application/json' -d '{
"set": {
  "full_txt": {
    "srcField": "_src_",
    "mapUniqueKeyOnly" : true,
    "df": "text"
}}}'

V2 API SolrCloud

 curl http://localhost:8983/api/collections/techproducts/config/params -H 'Content-type:application/json' -d '{
"set": {
  "full_txt": {
    "srcField": "_src_",
    "mapUniqueKeyOnly" : true,
    "df": "text"
}}}'

要使用这些参数,请在每个请求中发送参数 useParams=full_txt