轉換和索引自訂 JSON

如果您有 JSON 文件,想要在不將它們轉換為 Solr 結構的情況下進行索引,您可以透過在更新請求中包含一些參數將它們新增到 Solr。

這些參數提供關於如何將單個 JSON 檔案分割成多個 Solr 文件,以及如何將欄位對應到 Solr 結構描述的資訊。一個或多個有效的 JSON 文件可以使用組態參數傳送到 /update/json/docs 路徑。

對應參數

這些參數可讓您定義應如何讀取 JSON 檔案以產生多個 Solr 文件。

split

選用

預設值:none

定義將輸入 JSON 分割成多個 Solr 文件的路徑,如果您在單個 JSON 檔案中有多個文件,則此為必要參數。如果整個 JSON 構成單個 Solr 文件,則路徑必須為「/」。

可以傳遞多個 split 路徑,方法是以管線 (|) 分隔它們,例如:split=/|/foo|/foo/bar。如果一個路徑是另一個路徑的子路徑,它們會自動成為子文件。

f

必要

預設值:none

提供多值對應,以將文件欄位名稱對應到 Solr 欄位名稱。參數的格式為 目標欄位名稱:json 路徑,例如 f=first:/firstjson 路徑 為必要。目標欄位名稱 為 Solr 文件欄位名稱,並且為選用。如果未指定,則會自動從輸入 JSON 推導得出。預設目標欄位名稱是欄位的完整限定名稱。

此處可以使用萬用字元,請參閱下方 使用萬用字元表示欄位名稱 以取得更多資訊。

mapUniqueKeyOnly

選用

預設值:false

當輸入 JSON 中的欄位在 schema 中不可用,且未啟用無模式模式時,此參數特別方便。這會將所有欄位索引到預設搜尋欄位 (使用 df 參數),且只有 uniqueKey 欄位會對應到 schema 中的對應欄位。如果輸入 JSON 沒有 uniqueKey 欄位的值,則會為其產生一個 UUID。

df

選用

預設值:none

如果啟用 mapUniqueKeyOnly 旗標,更新處理器需要一個欄位來索引資料。這個欄位與其他處理器用作預設搜尋欄位的欄位相同。

srcField

選用

預設值:none

這是 JSON 來源將儲存到的欄位名稱。這只有在 split=/ 時才能使用 (也就是說,您希望將 JSON 輸入檔索引為單一 Solr 文件)。請注意,原子更新會導致該欄位與文件不同步。

echo

選用

預設值:false

這僅用於除錯目的。如果您希望將文件作為回應傳回,請將其設定為 true。不會索引任何內容。

例如,如果我們有一個包含兩個文件的 JSON 檔案,我們可以定義如下的更新請求

  • V1 API

  • V2 API 使用者管理/單節點 Solr

  • V2 API SolrCloud

curl 'https://127.0.0.1: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}
  ]
}'
curl 'https://127.0.0.1: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}
  ]
}'
curl 'https://127.0.0.1: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

  • V2 API 使用者管理/單節點 Solr

  • V2 API SolrCloud

curl 'https://127.0.0.1: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}
  ]
}'
curl 'https://127.0.0.1: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}
  ]
}'
curl 'https://127.0.0.1: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 輸入中欄位的內容加入到索引中,並使用相同的名稱作為欄位名稱。

如果欄位在索引之前不存在於 schema 中,則在索引期間會拒絕文件。因此,如果您不使用無模式模式,則必須預先建立所有欄位。但是,如果您在無模式模式下工作,則不存在的欄位會在使用 Solr 對欄位類型的最佳猜測下即時建立。

在多個請求中重複使用參數

您可以使用 Solr 的請求參數 API 來儲存和重複使用參數。

假設我們想定義參數,以在 exams 欄位分割文件,並對應其他幾個欄位。我們可以發出如下的 API 請求

  • V1 API

  • V2 API 使用者管理/單節點 Solr

  • V2 API SolrCloud

 curl https://127.0.0.1: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"]
 }}}'
curl https://127.0.0.1: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"]
 }}}'
curl https://127.0.0.1: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

  • V2 API 使用者管理/單節點 Solr

  • V2 API SolrCloud

curl 'https://127.0.0.1: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
    }
  ]
}'
curl 'https://127.0.0.1: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
    }
  ]
}'
curl 'https://127.0.0.1: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

  • V2 API 使用者管理/單節點 Solr

  • V2 API SolrCloud

curl 'https://127.0.0.1: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}
  ]
}'
curl 'https://127.0.0.1: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}
  ]
}'
curl 'https://127.0.0.1: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 文件,而無需擔心欄位和 schema。

  • V1 API

  • V2 API 使用者管理/單節點 Solr

  • V2 API SolrCloud

curl 'https://127.0.0.1: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}
  ]
}'
curl 'https://127.0.0.1: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}
  ]
}'
curl 'https://127.0.0.1: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}
  ]
}'

在以上範例中,我們已表示所有欄位都應該加入到 Solr 中名為 'txt' 的欄位。這會將多個欄位加入到單一欄位,因此您選擇的任何欄位都應該是多值欄位。

預設行為是使用節點的完整限定名稱 (FQN)。因此,如果我們沒有定義任何欄位對應,如下所示

  • V1 API

  • V2 API 使用者管理/單節點 Solr

  • V2 API SolrCloud

curl 'https://127.0.0.1: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}
  ]
}'
curl 'https://127.0.0.1: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}
  ]
}'
curl 'https://127.0.0.1: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

  • V2 API 使用者管理/單節點 Solr

  • V2 API SolrCloud

curl 'https://127.0.0.1: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}'
curl 'https://127.0.0.1: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}'
curl 'https://127.0.0.1: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

  • V2 API 使用者管理/單節點 Solr

  • V2 API SolrCloud

curl 'https://127.0.0.1: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}]'
curl 'https://127.0.0.1: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}]'
curl 'https://127.0.0.1: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. 預先建立的 Schema:使用 echo=true 將您的文件張貼到 /update/json/docs 端點。這會給您需要建立的欄位名稱清單。在您實際索引之前建立欄位

  3. 沒有 schema,只有全文搜尋:您需要做的就是對 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

  • V2 API 使用者管理/單節點 Solr

  • V2 API SolrCloud

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

若要使用這些參數,請在每個請求中傳送參數 useParams=full_txt