JSON 分面網域變更

分面計算會在文件的「網域」上運作。預設情況下,此網域包含主要查詢所比對的文件。對於子分面,網域包含父分面將其放入儲存區的所有文件。

使用者也可以覆寫分割資料的分面的「網域」,使用明確的 domain 屬性,其值是一個 JSON 物件,可支援各種選項,以在計算相關分面的儲存區之前,限制、擴展或完全變更原始網域。

domain 變更只能在執行資料分割的個別分面上指定,而不能在統計/度量分面或分面群組上指定。

具有 domain 變更的 *:* 查詢分面可用於將任何類型的多個子分面分組,以套用常見的網域變更。

新增網域篩選器

網域變更最簡單的範例是指定將套用至現有網域的其他篩選器。這可以透過分面 domain 區塊中的 filter 關鍵字來完成。

  • curl

  • SolrJ

curl https://127.0.0.1:8983/solr/techproducts/query -d '
{
  "query": "*:*",
  "facet": {
    "categories": {
      "type": "terms",
      "field": "cat",
      "limit": 3,
      "domain": {
        "filter": "popularity:[5 TO 10]"
      }
    }
  }
}'
final TermsFacetMap categoryFacet =
    new TermsFacetMap("cat")
        .setLimit(3)
        .withDomain(new DomainMap().withFilter("popularity:[5 TO 10]"));
final JsonQueryRequest request =
    new JsonQueryRequest().setQuery("*:*").withFacet("categories", categoryFacet);
QueryResponse queryResponse = request.process(solrClient, COLLECTION_NAME);

filter 的值可以是單一查詢,以視為篩選器,也可以是篩選查詢的 JSON 清單。每個查詢可以是

  • 包含 Solr 查詢語法的查詢字串。

  • 參考包含 Solr 查詢語法的請求參數,格式為:{param: <request_param_name>}。可以參考在 JSON Request API 的 查詢 金鑰下定義的 DSL 語法中的一個或多個查詢。參考的參數可能具有 0 個(不存在)或多個值。

    • 當未指定任何值時,不會套用任何篩選器,也不會擲回任何錯誤。

    • 當指定許多值時,每個值都會經過剖析,並結合使用作為篩選器。

以下是參考 DSL 查詢的範例

curl https://127.0.0.1:8983/solr/techproducts/query -d '
{
  "query": "*:*",
  "queries": {
      "sample_filtrs":[
           {"field":{"f":"text", "query":"usb"}},
           {"field":{"f":"text", "query":"lcd"}}
        ],
        "another_filtr":
            {"field":{"f":"text", "query":"usb"}}
  },
  "facet": {
    "usblcd": {
      "type": "terms",
      "field": "cat",
      "limit": 3,
      "domain": {
        "filter": {"param":"sample_filtrs"}
      }
    },
    "justusb": {
      "type": "terms",
      "field": "cat",
      "limit": 3,
      "domain": {
        "filter": {"param":"another_filtr"}
      }
    }
  }
}'

filter 選項與其他 domain 變更選項結合時,篩選會在其他網域變更發生之後套用。

篩選器排除

也可以使用 excludeTags 關鍵字來捨棄或忽略特定的已標記查詢篩選器,以擴展網域。

以下範例中會使用此方法來顯示符合搜尋的前兩名製造商。搜尋結果符合篩選器 manu_id_s:apple,但計算出的分面會捨棄此篩選器,並在捨棄 manu_id_s 篩選器後擴展網域。

  • curl

  • SolrJ

curl https://127.0.0.1:8983/solr/techproducts/query -d '
{
  "query": "cat:electronics",
  "filter": "{!tag=MANU}manu_id_s:apple",
  "facet": {
    "stock": {"type": "terms", "field": "inStock", "limit": 2},
    "manufacturers": {
      "type": "terms",
      "field": "manu_id_s",
      "limit": 2,
      "domain": { "excludeTags":"MANU" }
    }
  }
}'
final TermsFacetMap inStockFacet = new TermsFacetMap("inStock").setLimit(2);
final TermsFacetMap allManufacturersFacet =
    new TermsFacetMap("manu_id_s")
        .setLimit(2)
        .withDomain(new DomainMap().withTagsToExclude("MANU"));
final JsonQueryRequest request =
    new JsonQueryRequest()
        .setQuery("cat:electronics")
        .withFilter("{!tag=MANU}manu_id_s:apple")
        .withFacet("stock", inStockFacet)
        .withFacet("manufacturers", allManufacturersFacet);
QueryResponse queryResponse = request.process(solrClient, COLLECTION_NAME);

excludeTags 的值可以是單一字串標籤、字串標籤陣列,或單一字串中以逗號分隔的標籤。

excludeTags 選項與其他 domain 變更選項結合時,它會在任何其他網域變更發生之前擴展網域。

另請參閱有關多重選擇分面的章節。

任意網域查詢

當您希望根據任意一組文件計算分面時,可以指定 query 網域,而無論原始網域為何。最常見的使用案例是針對集合的特定子集計算頂層分面,而無論主要查詢為何。但它在建置 語意知識圖譜時,在巢狀分面上也可能很有用。

範例

  • curl

  • SolrJ

curl https://127.0.0.1:8983/solr/techproducts/query -d '
{
  "query": "apple",
  "facet": {
    "popular_categories": {
      "type": "terms",
      "field": "cat",
      "domain": { "query": "popularity:[8 TO 10]" },
      "limit": 3
    }
  }
}'
final TermsFacetMap inStockFacet = new TermsFacetMap("inStock").setLimit(2);
final TermsFacetMap popularCategoriesFacet =
    new TermsFacetMap("cat")
        .withDomain(new DomainMap().withQuery("popularity:[8 TO 10]"))
        .setLimit(3);
final JsonQueryRequest request =
    new JsonQueryRequest()
        .setQuery("apple")
        .withFacet("popular_categories", popularCategoriesFacet);
QueryResponse queryResponse = request.process(solrClient, COLLECTION_NAME);

query 的值可以是單一查詢,或查詢的 JSON 清單。每個查詢可以是

  • 包含 Solr 查詢語法的查詢字串。

  • 一個參考請求參數的語法,其中包含 Solr 查詢語法,格式如下:{param: <request_param_name>}。被參考的參數可能沒有值 (不存在) 或有多個值。

    • 當沒有指定值時,不會拋出錯誤。

    • 當指定多個值時,每個值都會被解析並用作查詢。

雖然 query 域可以與額外的 filter 域結合使用,但無法同時使用 excludeTags,因為標籤會變得毫無意義:query 域已經完全忽略了頂層查詢和所有先前的篩選器。

區塊連結域變更

當集合包含巢狀文件時,可以使用 blockChildrenblockParent 域選項,將現有域(包含一種文件類型)轉換為包含與原始域文件具有指定關係(子文件或父文件)的文件域。

這兩個選項的工作方式與相應的區塊連結查詢解析器類似,方法是接收一個單一字串查詢,該查詢專門匹配集合中的所有父文件。如果使用 blockParent,則結果域將包含來自原始域的所有子文件的父文件。如果使用 blockChildren,則結果域將包含來自原始域的所有父文件的子文件。通常,需要在父文件中計算子文件的 facet,這可以使用 uniqueBlock(_root_) 來完成,如區塊連結 Facet 計數中所述。

{
  "colors": {                         (1)
    "type": "terms",
    "field": "sku_color",             (2)
    "facet" : {
      "brands" : {
        "type": "terms",
        "field": "product_brand",     (3)
        "domain": {
          "blockParent": "doc_type:product"
        }
      }}}}
1 此範例假設我們的父文件對應於產品,子文件對應於具有獨特顏色的個別 SKU,並且我們的原始查詢是針對 SKU 文件。
2 colors facet 將針對符合我們搜尋條件的所有原始 SKU 文件進行計算。
3 對於 colors facet 中的每個 bucket,所有符合條件的 SKU 文件集合將被轉換為相應的父產品文件集合。產生的 brands 子 facet 將計算每個品牌存在多少個產品文件(這些產品文件具有相關顏色的 SKU)。

連結查詢域變更

可以使用 join 域變更選項,指定任意的 fromto 欄位,用於將現有域轉換為相關的文件集。

它的工作方式與連結查詢解析器類似,並且在處理多 shard 集合時具有相同的限制。

範例

{
  "colors": {
    "type": "terms",
    "field": "sku_color",
    "facet": {
      "brands": {
        "type": "terms",
        "field": "product_brand",
        "domain" : {
          "join" : {
            "from": "product_id_of_this_sku",
            "to": "id"
          },
          "filter": "doc_type:product"
        }
      }
    }
  }
}

join 域變更支援一個可選的 method 參數,允許使用者指定他們想在這個域轉換中使用哪種連結實作。Solr 提供了幾種連結實作,每種都有不同的效能特性。有關這些實作及其權衡的更多資訊,請參閱method 參數文件。連結域變更支援除了 crossCollection 以外的所有 method 值。

圖形遍歷域變更

graph 域變更選項的工作方式與 join 域選項類似,但可以執行從現有域 from 到其他文件的多跳 to 遍歷。

它的工作方式與圖形查詢解析器非常相似,支援其所有可選參數,並且在處理多 shard 集合時具有相同的限制。

範例

{
  "related_brands": {
    "type": "terms",
    "field": "brand",
    "domain": {
      "graph": {
        "from": "related_product_ids",
        "to": "id",
        "maxDepth": 3
      }
    }
  }
}