ネストされた子ドキュメントの検索

このセクションでは、深くネストされたドキュメントを検索するために使用できる潜在的なテクニックを紹介し、Solr のクエリパーサーとドキュメントトランスフォーマーを使用して、より複雑なクエリをどのように構築できるかを示します。

これらの機能を使用するには、スキーマで _root__nest_path_ を宣言する必要があります。スキーマとインデックスの構成の詳細については、ネストされたドキュメントのインデクシング を参照してください。

このセクションでは、ネストされたドキュメントのファセットについては説明していません。ネストされたドキュメントのファセットについては、ブロック結合ファセットカウント セクションを参照してください。

クエリ例

今後の例では、ネストされたドキュメントのインデクシング で説明されているのと同じドキュメントを含むインデックスを想定します。

[{ "id": "P11!prod",
   "name_s": "Swingline Stapler",
   "description_t": "The Cadillac of office staplers ...",
   "skus": [ { "id": "P11!S21",
               "color_s": "RED",
               "price_i": 42,
               "manuals": [ { "id": "P11!D41",
                              "name_s": "Red Swingline Brochure",
                              "pages_i":1,
                              "content_t": "..."
                            } ]
             },
             { "id": "P11!S31",
               "color_s": "BLACK",
               "price_i": 3
             } ],
   "manuals": [ { "id": "P11!D51",
                  "name_s": "Quick Reference Guide",
                  "pages_i":1,
                  "content_t": "How to use your stapler ..."
                },
                { "id": "P11!D61",
                  "name_s": "Warranty Details",
                  "pages_i":42,
                  "content_t": "... lifetime guarantee ..."
                } ]
 },
 { "id": "P22!prod",
   "name_s": "Mont Blanc Fountain Pen",
   "description_t": "A Premium Writing Instrument ...",
   "skus": [ { "id": "P22!S22",
               "color_s": "RED",
               "price_i": 89,
               "manuals": [ { "id": "P22!D42",
                              "name_s": "Red Mont Blanc Brochure",
                              "pages_i":1,
                              "content_t": "..."
                            } ]
             },
             { "id": "P22!S32",
               "color_s": "BLACK",
               "price_i": 67
             } ],
   "manuals": [ { "id": "P22!D52",
                  "name_s": "How To Use A Pen",
                  "pages_i":42,
                  "content_t": "Start by removing the cap ..."
                } ]
 } ]

子ドキュメントトランスフォーマー

デフォルトでは、クエリに一致するドキュメントには、レスポンスにネストされた子が含まれていません。[child] ドキュメントトランスフォーマーを使用すると、クエリ結果をドキュメントの子孫でエンリッチできます。

このトランスフォーマーの詳細な説明、および構文と制限事項の詳細については、[child - ChildDocTransformerFactory] セクションを参照してください。

「staplers」を含む説明を持つすべてのドキュメントに一致する単純なクエリ

$ curl 'https://127.0.0.1:8983/solr/gettingstarted/select?omitHeader=true&q=description_t:staplers'
{
  "response":{"numFound":1,"start":0,"maxScore":0.30136836,"numFoundExact":true,"docs":[
      {
        "id":"P11!prod",
        "name_s":"Swingline Stapler",
        "description_t":"The Cadillac of office staplers ...",
        "_version_":1672933224035123200}]
  }}

[child] トランスフォーマーを追加した同じクエリを以下に示します。numFound は変更されておらず、まだ同じドキュメントセットに一致していることに注意してください。ただし、これらのドキュメントを返す場合は、ネストされた子も疑似フィールドとして返されます。

$ curl 'https://127.0.0.1:8983/solr/gettingstarted/select?omitHeader=true&q=description_t:staplers&fl=*,[child]'
{
  "response":{"numFound":1,"start":0,"maxScore":0.30136836,"numFoundExact":true,"docs":[
      {
        "id":"P11!prod",
        "name_s":"Swingline Stapler",
        "description_t":"The Cadillac of office staplers ...",
        "_version_":1672933224035123200,
        "skus":[
          {
            "id":"P11!S21",
            "color_s":"RED",
            "price_i":42,
            "_version_":1672933224035123200,
            "manuals":[
              {
                "id":"P11!D41",
                "name_s":"Red Swingline Brochure",
                "pages_i":1,
                "content_t":"...",
                "_version_":1672933224035123200}]},

          {
            "id":"P11!S31",
            "color_s":"BLACK",
            "price_i":3,
            "_version_":1672933224035123200}],
        "manuals":[
          {
            "id":"P11!D51",
            "name_s":"Quick Reference Guide",
            "pages_i":1,
            "content_t":"How to use your stapler ...",
            "_version_":1672933224035123200},

          {
            "id":"P11!D61",
            "name_s":"Warranty Details",
            "pages_i":42,
            "content_t":"... lifetime guarantee ...",
            "_version_":1672933224035123200}]}]
  }}

子クエリパーサー

{!child} クエリパーサーを使用すると、ラップされたクエリに一致する親ドキュメントの*子孫*ドキュメントを検索できます。このパーサーの詳細な説明については、ブロック結合子クエリパーサー セクションを参照してください。

上記で使用した description_t:staplers クエリをもう一度考えてみましょう。このクエリを {!child} クエリパーサーでラップすると、製品レベルのドキュメントを「一致」させて返す代わりに、元のクエリの*子孫*すべての子ドキュメントに一致します。

$ curl 'https://127.0.0.1:8983/solr/gettingstarted/select' -d 'omitHeader=true' -d 'q={!child of="*:* -_nest_path_:*"}description_t:staplers'
{
  "response":{"numFound":5,"start":0,"maxScore":0.30136836,"numFoundExact":true,"docs":[
      {
        "id":"P11!D41",
        "name_s":"Red Swingline Brochure",
        "pages_i":1,
        "content_t":"...",
        "_version_":1672933224035123200},
      {
        "id":"P11!S21",
        "color_s":"RED",
        "price_i":42,
        "_version_":1672933224035123200},
      {
        "id":"P11!S31",
        "color_s":"BLACK",
        "price_i":3,
        "_version_":1672933224035123200},
      {
        "id":"P11!D51",
        "name_s":"Quick Reference Guide",
        "pages_i":1,
        "content_t":"How to use your stapler ...",
        "_version_":1672933224035123200},
      {
        "id":"P11!D61",
        "name_s":"Warranty Details",
        "pages_i":42,
        "content_t":"... lifetime guarantee ...",
        "_version_":1672933224035123200}]
  }}

この例では、of パラメータとして *:* -_nest_path_:* を使用して、ネストパスを持たないすべてのドキュメント、つまりすべての「ルート」レベルのドキュメントを、可能な親のセットとして扱うことを示しています。

of パラメータを変更して特定の _nest_path_ レベルの祖先に一致させることにより、返す子のリストを絞り込むことができます。以下のクエリでは、/skus/* のプレフィックスを持つ _nest_path_ を*持たない*すべてのドキュメントを識別する of パラメータを使用して、skus のすべての子孫を検索し、price_i50 未満です。

$ curl 'https://127.0.0.1:8983/solr/gettingstarted/select' -d 'omitHeader=true' --data-urlencode 'q={!child of="*:* -_nest_path_:\\/skus\\/*"}(+price_i:[* TO 50] +_nest_path_:\/skus)'
{
  "response":{"numFound":1,"start":0,"maxScore":1.0,"numFoundExact":true,"docs":[
      {
        "id":"P11!D41",
        "name_s":"Red Swingline Brochure",
        "pages_i":1,
        "content_t":"...",
        "_version_":1675662666752851968}]
  }}
of での _nest_path_ スラッシュの二重エスケープ

上記の例では、_nest_path_/ 文字が of パラメータで「二重エスケープ」されていることに注意してください。

  • /正規表現クエリ として解釈されないようにするため、1レベルの \ エスケープが必要です。

  • of ローカルパラメータはクォートされた文字列であるため、追加の「エスケープ文字のエスケープ」レベルが必要です。そのため、最初の \ が保持され、クエリパーサーにそのまま渡されるように、2番目の \ が必要です。

(クエリ文字列の本文では、正規表現構文を防ぐために、1レベルの \ エスケープのみが必要であることがわかります。これは、クォートされた文字列のローカルパラメータではないためです)。

/ を特殊文字として扱わない 他のパーサー と共に パラメータ参照 を使用して、同じクエリをより冗長な形式で表現する方が便利な場合があります。

$ curl 'https://127.0.0.1:8983/solr/gettingstarted/select' -d 'omitHeader=true' --data-urlencode 'q={!child of=$block_mask}(+price_i:[* TO 50] +{!field f="_nest_path_" v="/skus"})' --data-urlencode 'block_mask=(*:* -{!prefix f="_nest_path_" v="/skus/"})'

親クエリパーサー

{!child} クエリパーサーの逆は {!parent} クエリパーサーです。これは、ラップされたクエリに一致する子ドキュメントの *祖先* ドキュメントを検索できます。このパーサーの詳細な説明については、ブロック結合親クエリパーサー のセクションを参照してください。

最初に、正確に 1 ページを持つすべての「マニュアル」タイプのドキュメントを検索するこの例を考えてみましょう。

$ curl 'https://127.0.0.1:8983/solr/gettingstarted/select?omitHeader=true&q=pages_i:1'
{
  "response":{"numFound":3,"start":0,"maxScore":1.0,"numFoundExact":true,"docs":[
      {
        "id":"P11!D41",
        "name_s":"Red Swingline Brochure",
        "pages_i":1,
        "content_t":"...",
        "_version_":1676585794196733952},
      {
        "id":"P11!D51",
        "name_s":"Quick Reference Guide",
        "pages_i":1,
        "content_t":"How to use your stapler ...",
        "_version_":1676585794196733952},
      {
        "id":"P22!D42",
        "name_s":"Red Mont Blanc Brochure",
        "pages_i":1,
        "content_t":"...",
        "_version_":1676585794347728896}]
  }}

そのクエリを {!parent} クエリでラップして、これらのマニュアルの祖先であるすべての製品の詳細を返すことができます。

$ curl 'https://127.0.0.1:8983/solr/gettingstarted/select' -d 'omitHeader=true' --data-urlencode 'q={!parent which="*:* -_nest_path_:*"}(+_nest_path_:\/skus\/manuals +pages_i:1)'
{
  "response":{"numFound":2,"start":0,"maxScore":1.4E-45,"numFoundExact":true,"docs":[
      {
        "id":"P11!prod",
        "name_s":"Swingline Stapler",
        "description_t":"The Cadillac of office staplers ...",
        "_version_":1676585794196733952},
      {
        "id":"P22!prod",
        "name_s":"Mont Blanc Fountain Pen",
        "description_t":"A Premium Writing Instrument ...",
        "_version_":1676585794347728896}]
  }}

この例では、which パラメータ として *:* -_nest_path_:* を使用して、ネストパスを持たないすべてのドキュメント、つまりすべての「ルート」レベルのドキュメントを、可能な親のセットとして考慮することを示しています。

which パラメータを変更して特定の _nest_path_ レベルの祖先に一致させることで、返す祖先のタイプを変更できます。以下のクエリでは、正確に 1 ページのマニュアルの祖先である sku/skus/* というプレフィックスを持つ _nest_path_ を *持たない* すべてのドキュメントを識別する which パラメータを使用)を検索します。

$ curl 'https://127.0.0.1:8983/solr/gettingstarted/select' -d 'omitHeader=true' --data-urlencode 'q={!parent which="*:* -_nest_path_:\\/skus\\/*"}(+_nest_path_:\/skus\/manuals +pages_i:1)'
{
  "response":{"numFound":2,"start":0,"maxScore":1.4E-45,"numFoundExact":true,"docs":[
      {
        "id":"P11!S21",
        "color_s":"RED",
        "price_i":42,
        "_version_":1676585794196733952},
      {
        "id":"P22!S22",
        "color_s":"RED",
        "price_i":89,
        "_version_":1676585794347728896}]
  }}

上記の例では、_nest_path_/ 文字は、{!child} パーサーの of パラメータに関して上記で説明したのと同じ理由で、which パラメータで「二重エスケープ」されています。

ブロック結合クエリパーサーと子ドキュメントトランスフォーマーの組み合わせ

これらの2つのパーサーと `[child]` トランスフォーマーの組み合わせにより、非常に強力なクエリをシームレスに作成できます。

たとえば、次のようなクエリがあります。

  • 返される(sku)ドキュメントの色は「RED」である必要があります。

  • 返される(sku)ドキュメントは、次の条件を持つルートレベル(製品)ドキュメントの子孫である必要があります。

    • コンテンツに「lifetime guarantee」を含む直接の子「マニュアル」ドキュメントを持つ

      • 各リターン(sku)ドキュメントには、それが持つ子孫(マニュアル)ドキュメントも含まれます。

$ curl 'https://127.0.0.1:8983/solr/gettingstarted/select' -d 'omitHeader=true' -d 'fq=color_s:RED' --data-urlencode 'q={!child of="*:* -_nest_path_:*" filters=$parent_fq}' --data-urlencode 'parent_fq={!parent which="*:* -_nest_path_:*"}(+_nest_path_:"/manuals" +content_t:"lifetime guarantee")' -d 'fl=*,[child]'
{
  "response":{"numFound":1,"start":0,"maxScore":1.4E-45,"numFoundExact":true,"docs":[
      {
        "id":"P11!S21",
        "color_s":"RED",
        "price_i":42,
        "_version_":1676585794196733952,
        "manuals":[
          {
            "id":"P11!D41",
            "name_s":"Red Swingline Brochure",
            "pages_i":1,
            "content_t":"...",
            "_version_":1676585794196733952}]}]
  }}