Solr練習(xí)2:修改架構(gòu)和索引影片數(shù)據(jù)

2018-12-25 10:17 更新

本練習(xí)將在最后一個(gè)基礎(chǔ)上構(gòu)建,向您介紹索引架構(gòu)和 Solr 強(qiáng)大的 faceting 功能。

重新啟動(dòng) Solr

如果在上一節(jié)的練習(xí)中您沒(méi)有停止 Solr,則繼續(xù)進(jìn)行本節(jié)內(nèi)容。

但是,如果您確實(shí)需要重新啟動(dòng) Solr,請(qǐng)發(fā)出以下命令:

./bin/solr start -c -p 8983 -s example/cloud/node1/solr

這將啟動(dòng)第一個(gè)節(jié)點(diǎn)。當(dāng)它完成后,啟動(dòng)第二個(gè)節(jié)點(diǎn),并告訴它如何連接到 ZooKeeper:

./bin/solr start -c -p 7574 -s example/cloud/node2/solr -z localhost:9983

創(chuàng)建一個(gè)新的集合

我們將在這個(gè)練習(xí)中使用一個(gè)全新的數(shù)據(jù)集,所以最好有一個(gè)新的集合,而不是試圖重復(fù)使用之前的集合。

其中一個(gè)原因是我們將在 Solr 中使用一個(gè)名為“字段猜測(cè)”的特性,在這個(gè)特性中,Solr 試圖猜測(cè)索引它時(shí)字段中的數(shù)據(jù)是什么類型的。它還會(huì)自動(dòng)在架構(gòu)中為出現(xiàn)在傳入文檔中的新字段創(chuàng)建新字段。這種模式被稱為 “無(wú)架構(gòu)”。我們將看到這種方法的優(yōu)點(diǎn)和局限性,以幫助您決定在實(shí)際應(yīng)用中如何以及如何使用它。

什么是“架構(gòu)”,為什么我需要一個(gè)?

Solr 的架構(gòu)是一個(gè)單獨(dú)的文件(以 XML 格式),它存儲(chǔ)了有關(guān) Solr 應(yīng)該理解的字段和字段類型的詳細(xì)信息。架構(gòu)不僅定義字段或字段類型名稱,而且定義字段在索引之前應(yīng)該發(fā)生的任何修改。例如,如果要確保輸入“abc” 的用戶和輸入“ABC” 的用戶都能找到包含 “ABC” 的文檔,則需要進(jìn)行標(biāo)準(zhǔn)化(在這種情況下為小寫) )當(dāng)它被索引的時(shí)候 “ABC”,并且規(guī)范化用戶查詢以確保匹配。這些規(guī)則在您的架構(gòu)中定義。

在前面的教程中,我們提到了復(fù)制字段,這些字段是由來(lái)自其他字段的數(shù)據(jù)組成的字段。您還可以定義動(dòng)態(tài)字段,這些字段使用通配符(如 _t 或 _s)來(lái)動(dòng)態(tài)創(chuàng)建特定字段類型的字段。這些類型的規(guī)則也在架構(gòu)中定義。

在第一個(gè)練習(xí)中最初啟動(dòng) Solr 時(shí),我們可以選擇一個(gè) configSet 來(lái)使用。我們選擇的一個(gè)架構(gòu)是為我們稍后索引的數(shù)據(jù)預(yù)先定義的。這一次,我們將使用具有非常小的模式的 configSet,并讓 Solr 從數(shù)據(jù)中找出要添加的字段。

您要索引的數(shù)據(jù)與電影相關(guān),因此首先創(chuàng)建一個(gè)名為 “films” 的集合,該集合使用 _defaultconfigSet:

bin/solr create -c films -s 2 -rf 2

哇,等等。我們沒(méi)有指定一個(gè) configSet!沒(méi)關(guān)系,這 _default 是適當(dāng)?shù)拿?,因?yàn)樗悄J(rèn)的,如果你沒(méi)有指定一個(gè),就使用它。

我們沒(méi)有,但是,設(shè)置兩個(gè)參數(shù) -s 和 -rf。這些是分割集合的分割的數(shù)量(2)以及要?jiǎng)?chuàng)建的副本數(shù)量(2)。這相當(dāng)于我們?cè)诘谝粋€(gè)練習(xí)的互動(dòng)示例中所做的選擇。

你應(yīng)該看到如下輸出:

WARNING: Using _default configset. Data driven schema functionality is enabled by default, which is
         NOT RECOMMENDED for production use.

         To turn it off:
            curl http://localhost:7574/solr/films/config -d '{"set-user-property": {"update.autoCreateFields":"false"}}'

Connecting to ZooKeeper at localhost:9983 ...
INFO  - 2017-07-27 15:07:46.191; org.apache.solr.client.solrj.impl.ZkClientClusterStateProvider; Cluster at localhost:9983 ready
Uploading /7.0.0/server/solr/configsets/_default/conf for config films to ZooKeeper at localhost:9983

Creating new collection 'films' using command:
http://localhost:7574/solr/admin/collections?action=CREATE&name=films&numShards=2&replicationFactor=2&maxShardsPerNode=2&collection.configName=films

{
  "responseHeader":{
    "status":0,
    "QTime":3830},
  "success":{
    "192.168.0.110:8983_solr":{
      "responseHeader":{
        "status":0,
        "QTime":2076},
      "core":"films_shard2_replica_n1"},
    "192.168.0.110:7574_solr":{
      "responseHeader":{
        "status":0,
        "QTime":2494},
      "core":"films_shard1_replica_n2"}}}

命令打印的第一件事是關(guān)于在生產(chǎn)中不使用這個(gè) configSet 的警告。這是由于我們稍后會(huì)涉及的一些限制。

否則,應(yīng)該創(chuàng)建集合。如果我們轉(zhuǎn)到:http:// localhost:8983 / solr /#/ films / collection-overview上的管理界面,我們應(yīng)該看到總覽屏幕。

為電影數(shù)據(jù)準(zhǔn)備無(wú)架構(gòu)

_defaultconfigSet 附帶的架構(gòu)有兩個(gè)并行的事情發(fā)生。

首先,我們使用一個(gè)“托管模式”,它被配置為只能被 Solr 的 Schema API 修改。這意味著我們不應(yīng)該手工編輯它,所以不會(huì)對(duì)從哪個(gè)來(lái)源進(jìn)行編輯造成混淆。Solr 的Schema API 允許我們對(duì)字段、字段類型和其他類型的模式規(guī)則進(jìn)行更改。

其次,我們使用 solrconfig.xml 文件中配置的“字段猜測(cè)” (并包括 Solr 的各種配置設(shè)置)。字段猜測(cè)的目的是讓我們開(kāi)始使用 Solr,而不必在嘗試為索引建立索引之前定義我們認(rèn)為將在我們的文檔中的所有字段。這就是為什么我們稱之為“無(wú)架構(gòu)”的原因,因?yàn)槟梢钥焖賳?dòng),讓 Solr 在您遇到文檔時(shí)為您創(chuàng)建字段。

聽(tīng)起來(lái)不錯(cuò)!但是有限制。如果它猜錯(cuò)了,您不能改變很多關(guān)于一個(gè)字段的數(shù)據(jù)已經(jīng)索引后,而不必重新索引。如果我們只有幾千個(gè)可能并不壞的文檔,但是如果您擁有數(shù)百萬(wàn)甚至數(shù)百萬(wàn)個(gè)文檔,或者更糟糕的是無(wú)法再訪問(wèn)原始數(shù)據(jù),這可能是一個(gè)真正的問(wèn)題。

出于這些原因,Solr 社區(qū)不建議在沒(méi)有您自己定義的架構(gòu)的情況下進(jìn)行生產(chǎn)。通過(guò)這個(gè),我們的意思是無(wú)架構(gòu)功能可以從頭開(kāi)始,但是您仍然應(yīng)該始終確保您的架構(gòu)符合您希望數(shù)據(jù)索引的方式以及用戶將如何查詢它的期望。

可以將無(wú)架構(gòu)功能與定義的架構(gòu)混合使用。使用 Schema API,您可以定義一些您想要控制的字段,然后讓 Solr 猜測(cè)其他不太重要的字段,或者通過(guò)測(cè)試確信自己的信心會(huì)被猜測(cè)到您滿意。這就是我們要在這里做的。

創(chuàng)建“name”字段

我們要索引的電影資料,每部電影都有少量的字段:一個(gè) ID、導(dǎo)演姓名、電影名稱、發(fā)行日期和類型。

如果您查看其中一個(gè)文件 example/films,您將看到 2006 年發(fā)行的第一部影片名為 .45。作為數(shù)據(jù)集中的第一個(gè)文檔,Solr 將根據(jù)記錄中的數(shù)據(jù)猜測(cè)字段類型。如果我們繼續(xù)索引這些數(shù)據(jù),那么第一個(gè)影片名稱將會(huì)告訴 Solr 該字段類型是一個(gè) “float” 數(shù)字字段,并且將會(huì)創(chuàng)建一個(gè) “name” 的字段,類型為 FloatPointField。此記錄之后的所有數(shù)據(jù)將被預(yù)期為浮動(dòng)的。

那么,這是行不通的。我們有一個(gè)名字,像一個(gè)強(qiáng)大的風(fēng)和雞運(yùn)行,這是字符串 - 決不是數(shù)字,而不是浮動(dòng)。如果我們讓 Solr 猜測(cè) “name” 字段是一個(gè)浮點(diǎn)數(shù),那么稍后的標(biāo)題會(huì)導(dǎo)致一個(gè)錯(cuò)誤,索引將失敗。

在索引數(shù)據(jù)之前,我們可以做的是在 Solr 中設(shè)置 “name” 字段,以確保 Solr 始終將其解釋為一個(gè)字符串。在命令行輸入這個(gè) curl 命令:

curl -X POST -H 'Content-type:application/json' --data-binary '{"add-field": {"name":"name", "type":"text_general", "multiValued":false, "stored":true}}' http://localhost:8983/solr/films/schema

該命令使用 Schema API 來(lái)顯式定義一個(gè)名為 “name” 的字段,該字段的字段類型為 “text_general”(一個(gè)文本字段)。它不會(huì)被允許有多個(gè)值,但它將被存儲(chǔ)(這意味著它可以通過(guò)查詢來(lái)檢索)。

您也可以使用管理界面來(lái)創(chuàng)建字段,但對(duì)字段屬性的控制較少。但是,它將為我們的案件工作:

Solr練習(xí):創(chuàng)建字段

創(chuàng)建一個(gè)“catchall”復(fù)制字段

在我們開(kāi)始索引之前還有一個(gè)更改要做。

在第一個(gè)練習(xí)中,當(dāng)我們查詢已經(jīng)建立索引的文檔時(shí),我們不需要指定一個(gè)字段進(jìn)行搜索,因?yàn)槲覀兪褂玫呐渲帽辉O(shè)置為將字段復(fù)制到一個(gè) text 字段中,并且在查詢中沒(méi)有定義其他字段時(shí),該字段是默認(rèn)值。

我們現(xiàn)在使用的配置沒(méi)有這個(gè)規(guī)則。我們需要定義一個(gè)字段來(lái)搜索每個(gè)查詢。然而,我們可以通過(guò)定義一個(gè)復(fù)制字段來(lái)設(shè)置一個(gè)“catchall 字段”,該字段將從所有字段獲取所有數(shù)據(jù)并將其索引到一個(gè)名為 text 的字段中。

您可以使用管理用戶界面或架構(gòu) API。

在命令行中,再次使用 Schema API 來(lái)定義一個(gè)復(fù)制字段:

curl -X POST -H 'Content-type:application/json' --data-binary '{"add-copy-field" : {"source":"","dest":"text"}}' http://localhost:8983/solr/films/schema

在管理界面中,選擇添加復(fù)制字段,然后填寫您的字段的來(lái)源和目的地,如此屏幕截圖所示。

Solr創(chuàng)建一個(gè)復(fù)制字段

這是做所有字段的副本,并將數(shù)據(jù)放入 “text” 字段。

Tip:使用您的生產(chǎn)數(shù)據(jù)進(jìn)行此工作可能非常昂貴,因?yàn)樗鼤?huì)告訴 Solr 有效地將所有內(nèi)容索引兩次。它將使索引更慢,并使索引更大。使用您的生產(chǎn)數(shù)據(jù),您將希望確保只復(fù)制真正為您的應(yīng)用程序保證的字段。

好的,現(xiàn)在我們已經(jīng)準(zhǔn)備好索引數(shù)據(jù)并開(kāi)始了。

索引樣本電影數(shù)據(jù)

我們將索引的電影數(shù)據(jù)位于您的安裝目錄 example/films 中。它有三種格式:JSON、XML 和 CSV。選擇其中的一種格式,并將其索引到 “電影” 集合中(在每個(gè)示例中,一個(gè)命令用于 Unix / MacOS,另一個(gè)用于 Windows):

索引 JSON 格式:

bin/post -c films example/films/films.json

C:\solr-7.0.0> java -jar -Dc=films -Dauto example\exampledocs\post.jar example\films.json

索引 XML 格式:

bin/post -c films example/films/films.xml

C:\solr-7.0.0> java -jar -Dc=films -Dauto example\exampledocs\post.jar example\films.xml

索引 CSV 格式:

bin/post -c films example/films/films.csv -params "f.genre.split=true&f.directed_by.split=true&f.genre.separator=|&f.directed_by.separator=|"

C:\solr-7.0.0> java -jar -Dc=films -Dparams=f.genre.split=true&f.directed_by.split=true&f.genre.separator=|&f.directed_by.separator=| -Dauto example\exampledocs\post.jar example\films\*.csv

每個(gè)命令都包含這些主要參數(shù):

  • -c films:這是 Solr 收集索引數(shù)據(jù)。
  • example/films/films.json(或 films.xml 或 films.csv):這是數(shù)據(jù)文件索引的路徑。您可以簡(jiǎn)單地提供該文件所在的目錄,但由于您知道要編制索引的格式,因此指定該格式的確切文件效率更高。

請(qǐng)注意,CSV 命令包含額外的參數(shù)。這是為了確保 “genre” 和 “directed_by” 列中的多值條目被 pipe(|)字符分隔,在此文件中用作分隔符。告訴 Solr 這樣分割這些列將確保正確的數(shù)據(jù)索引。

每個(gè)命令將產(chǎn)生類似于索引 JSON 時(shí)看到的下面的輸出:

$ ./bin/post -c films example/films/films.json
/bin/java -classpath /solr-{solr-docs-version}.0/dist/solr-core-{solr-docs-version}.0.jar -Dauto=yes -Dc=films -Ddata=files org.apache.solr.util.SimplePostTool example/films/films.json
SimplePostTool version 5.0.0
Posting files to [base] url http://localhost:8983/solr/films/update...
Entering auto mode. File endings considered are xml,json,jsonl,csv,pdf,doc,docx,ppt,pptx,xls,xlsx,odt,odp,ods,ott,otp,ots,rtf,htm,html,txt,log
POSTing file films.json (application/json) to [base]/json/docs
1 files indexed.
COMMITting Solr index changes to http://localhost:8983/solr/films/update...
Time spent: 0:00:00.878

如果您進(jìn)入影片管理界面(http:// localhost:8983 / solr /#/ films / query)中的查詢屏幕并點(diǎn)擊執(zhí)行查詢,您應(yīng)該會(huì)看到 1100 個(gè)結(jié)果,前10個(gè)返回到屏幕。

讓我們做一個(gè)查詢,看看 “catchall” 字段是否正常工作。在 q 框中輸入“喜劇”,然后再次點(diǎn)擊“ 執(zhí)行查詢”。你應(yīng)該看到得到417個(gè)結(jié)果。

Faceting

Solr 最受歡迎的功能之一就是 faceting。faceting 允許將搜索結(jié)果排列成子集(或 buckets 或 categories),為每個(gè)子集提供計(jì)數(shù)。有幾種類型的 faceting:字段值、數(shù)字和日期范圍、樞軸(決策樹(shù))和任意查詢 faceting。

字段 Facets

除了提供搜索結(jié)果之外,Solr 查詢還可以返回包含整個(gè)結(jié)果集中每個(gè)唯一值的文檔的數(shù)量。

在“管理用戶界面查詢”選項(xiàng)卡上,如果選中該 facet 復(fù)選框,則會(huì)看到幾個(gè)與方面相關(guān)的選項(xiàng):

Solr練習(xí)

要查看所有文檔(q=:)中的 facet 計(jì)數(shù):打開(kāi) faceting(facet=true),并通過(guò) facet.fieldparam 指定要打開(kāi)的字段。如果您只想要 facet,并且沒(méi)有文檔內(nèi)容,請(qǐng)指定 rows=0。下面的 curl 命令將返回 genre_str 字段的 facet 計(jì)數(shù):

curl "http://localhost:8983/solr/films/select?q=:&rows=0&facet=true&facet.field=genre_str"

在您的終端中,您會(huì)看到如下所示的內(nèi)容:

{
  "responseHeader":{
    "zkConnected":true,
    "status":0,
    "QTime":11,
    "params":{
      "q":"*:*",
"facet.field":"genre_str", "rows":"0", "facet":"true"}}, "response":{"numFound":1100,"start":0,"maxScore":1.0,"docs":[] }, "facet_counts":{ "facet_queries":{}, "facet_fields":{ "genre_str":[ "Drama",552, "Comedy",389, "Romance Film",270, "Thriller",259, "Action Film",196, "Crime Fiction",170, "World cinema",167]}, "facet_ranges":{}, "facet_intervals":{}, "facet_heatmaps":{}}}

我們已經(jīng)在這里截?cái)嗔艘恍┹敵?,但是在?facet_counts 節(jié)中,默認(rèn)情況下,您會(huì)看到索引中每個(gè)類型的文檔使用的數(shù)量。Solr 有一個(gè)參數(shù) facet.mincount,可以用來(lái)限制只有那些包含一定數(shù)量的文檔的 facets(這個(gè)參數(shù)在 UI 中沒(méi)有顯示)?;蛘?,您也許需要所有的方面,并且讓您的應(yīng)用程序的前端控制如何顯示給用戶。

如果你想控制一個(gè) bucket 中的物品數(shù)量,你可以做這樣的事情:

curl "http://localhost:8983/solr/films/select?=&q=:&facet.field=genre_str&facet.mincount=200&facet=on&rows=0"

你只能看到4個(gè)方面返回。

還有很多其他參數(shù)可以幫助您控制 Solr 如何構(gòu)建 facets 和 facet 列表。我們將在本練習(xí)中介紹其中的一部分,但你也可以在 Faceting 部分了解更多的細(xì)節(jié)。

范圍 Facets

對(duì)于數(shù)字或日期,通常希望將 facet 計(jì)數(shù)劃分為范圍而不是離散值。數(shù)字范圍 faceting 的一個(gè)主要例子是,使用我們以前的練習(xí)中的例子 techproducts 數(shù)據(jù):price。在 /browseUI 中,它看起來(lái)像這樣:

Solr練習(xí)

電影數(shù)據(jù)包括電影的發(fā)行日期,我們可以使用它來(lái)創(chuàng)建日期范圍方面,這是范圍方面的另一個(gè)常見(jiàn)用途。

Solr 管理用戶界面還不支持范圍方面的選項(xiàng),因此您將需要使用 curl 或類似的命令行工具以下示例。

如果我們構(gòu)造一個(gè)如下所示的查詢:

curl 'http://localhost:8983/solr/films/select?q=:&rows=0'\
    '&facet=true'\
    '&facet.range=initial_release_date'\
    '&facet.range.start=NOW-20YEAR'\
    '&facet.range.end=NOW'\
    '&facet.range.gap=%2B1YEAR'

這將要求所有的電影,并要求他們從20年前(我們最早的發(fā)布日期在2000年)開(kāi)始到今天結(jié)束的年份。請(qǐng)注意,此查詢?cè)俅螌?URL 編碼 + 為 %2B。

在終端你會(huì)看到:

{
  "responseHeader":{
    "zkConnected":true,
    "status":0,
    "QTime":8,
    "params":{
      "facet.range":"initial_release_date",
      "facet.limit":"300",
      "q":"*:*",
"facet.range.gap":"+1YEAR", "rows":"0", "facet":"on", "facet.range.start":"NOW-20YEAR", "facet.range.end":"NOW"}}, "response":{"numFound":1100,"start":0,"maxScore":1.0,"docs":[] }, "facet_counts":{ "facet_queries":{}, "facet_fields":{}, "facet_ranges":{ "initial_release_date":{ "counts":[ "1997-07-28T17:12:06.919Z",0, "1998-07-28T17:12:06.919Z",0, "1999-07-28T17:12:06.919Z",48, "2000-07-28T17:12:06.919Z",82, "2001-07-28T17:12:06.919Z",103, "2002-07-28T17:12:06.919Z",131, "2003-07-28T17:12:06.919Z",137, "2004-07-28T17:12:06.919Z",163, "2005-07-28T17:12:06.919Z",189, "2006-07-28T17:12:06.919Z",92, "2007-07-28T17:12:06.919Z",26, "2008-07-28T17:12:06.919Z",7, "2009-07-28T17:12:06.919Z",3, "2010-07-28T17:12:06.919Z",0, "2011-07-28T17:12:06.919Z",0, "2012-07-28T17:12:06.919Z",1, "2013-07-28T17:12:06.919Z",1, "2014-07-28T17:12:06.919Z",1, "2015-07-28T17:12:06.919Z",0, "2016-07-28T17:12:06.919Z",0], "gap":"+1YEAR", "start":"1997-07-28T17:12:06.919Z", "end":"2017-07-28T17:12:06.919Z"}}, "facet_intervals":{}, "facet_heatmaps":{}}}

樞軸 Facets

另一個(gè) faceting 類型是數(shù)據(jù)透視 facets,也稱為“決策樹(shù)”,允許兩個(gè)或多個(gè)字段為所有各種可能的組合嵌套。使用電影數(shù)據(jù),可以使用數(shù)據(jù)透視面來(lái)查看 “Drama” 類別(genre_str 字段)中有多少電影由導(dǎo)演指導(dǎo)。以下是如何獲取此方案的原始數(shù)據(jù):

curl "http://localhost:8983/solr/films/select?q=:&rows=0&facet=on&facet.pivot=genre_str,directed_by_str"

這導(dǎo)致了以下回應(yīng),其中顯示了每個(gè)類別和導(dǎo)演組合的一個(gè)方面:

{"responseHeader":{
    "zkConnected":true,
    "status":0,
    "QTime":1147,
    "params":{
      "q":"*:*",
"facet.pivot":"genre_str,directed_by_str", "rows":"0", "facet":"on"}}, "response":{"numFound":1100,"start":0,"maxScore":1.0,"docs":[] }, "facet_counts":{ "facet_queries":{}, "facet_fields":{}, "facet_ranges":{}, "facet_intervals":{}, "facet_heatmaps":{}, "facet_pivot":{ "genre_str,directed_by_str":[{ "field":"genre_str", "value":"Drama", "count":552, "pivot":[{ "field":"directed_by_str", "value":"Ridley Scott", "count":5}, { "field":"directed_by_str", "value":"Steven Soderbergh", "count":5}, { "field":"directed_by_str", "value":"Michael Winterbottom", "count":4}}]}]}}}

我們也截?cái)嗔诉@個(gè)輸出 - 你會(huì)在屏幕上看到很多流派和導(dǎo)演。

Solr 練習(xí)2總結(jié)

在這個(gè)練習(xí)中,我們進(jìn)一步了解了 Solr 如何在索引中組織數(shù)據(jù),以及如何使用 Schema API 來(lái)操作架構(gòu)文件的知識(shí)。我們還了解了 Solr 的一些 facets,包括范圍 facets和數(shù)據(jù)透視 facets。在這兩方面,我們只是抓住了可用選項(xiàng)的表面。如果你能做到這一點(diǎn),這是可能的!

像我們以前的練習(xí)一樣,這些數(shù)據(jù)可能與您的需求無(wú)關(guān)。我們可以通過(guò)刪除集合來(lái)清理我們的工作。為此,請(qǐng)?jiān)诿钚兄邪l(fā)出以下命令:

bin/solr delete -c films
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)