Contoh terperinci dari bentuk dan proyeksi di penyimpanan pengetahuan

Artikel ini memberikan contoh rinci yang melengkapi konsep tingkat tinggi dan artikel berbasis sintaksis dengan memandu Anda melalui langkah-langkah pembentukan dan proyeksi yang diperlukan untuk sepenuhnya mengekspresikan output dari set kemampuan kaya di penyimpanan pengetahuan.

Jika persyaratan aplikasi Anda membutuhkan beberapa keterampilan dan proyeksi, contoh ini dapat memberi Anda ide yang lebih baik tentang bagaimana bentuk dan proyeksi berpotongan.

Unduh definisi sampel

Contoh ini menggunakan aplikasi Postman Desktop dan API Search REST.

Kloning atau unduh azure-search-postman-samples di GitHub dan impor Kumpulan proyeksi untuk melewati contoh ini sendiri.

Siapkan data sampel

Dokumen sampel tidak secara khusus disertakan dengan kumpulan Proyeksi, tetapi file data demo pengayaan AI dari azure-search-sample-data memiliki teks dan gambar, serta akan bekerja dengan proyeksi yang dijelaskan dalam contoh ini.

Buat kontainer blob di Azure Storage dan unggah semua 14 item.

Saat berada di Azure Storage, salin string koneksi sehingga Anda dapat menentukannya dalam kumpulan Postman.

Contoh set kemampuan

Untuk memahami dependensi antara bentuk dan proyeksi, tinjau set kemampuan berikut yang menciptakan konten yang diperkaya. Skillset ini memproses gambar mentah dan teks, menghasilkan output yang akan dirujuk dalam bentuk dan proyeksi.

Perhatikan baik-baik output kemampuan (targetNames). Output yang ditulis ke pohon dokumen yang diperkaya direferensikan dalam proyeksi dan dalam bentuk (melalui kemampuan Shaper).

{
    "name": "projections-demo-ss",
    "description": "Skillset that enriches blob data found in "merged_content". The enrichment granularity is a document.",
    "skills": [
        {
            "@odata.type": "#Microsoft.Skills.Text.V3.EntityRecognitionSkill",
            "name": "#1",
            "description": null,
            "context": "/document/merged_content",
            "categories": [
                "Person",
                "Quantity",
                "Organization",
                "URL",
                "Email",
                "Location",
                "DateTime"
            ],
            "defaultLanguageCode": "en",
            "minimumPrecision": null,
            "inputs": [
                {
                    "name": "text",
                    "source": "/document/merged_content"
                },
                {
                    "name": "languageCode",
                    "source": "/document/language"
                }
            ],
            "outputs": [
                {
                    "name": "persons",
                    "targetName": "people"
                },
                {
                    "name": "organizations",
                    "targetName": "organizations"
                },
                {
                    "name": "locations",
                    "targetName": "locations"
                }
            ]
        },
        {
            "@odata.type": "#Microsoft.Skills.Text.KeyPhraseExtractionSkill",
            "name": "#2",
            "description": null,
            "context": "/document/merged_content",
            "defaultLanguageCode": "en",
            "maxKeyPhraseCount": null,
            "inputs": [
                {
                    "name": "text",
                    "source": "/document/merged_content"
                },
                {
                    "name": "languageCode",
                    "source": "/document/language"
                }
            ],
            "outputs": [
                {
                    "name": "keyPhrases",
                    "targetName": "keyphrases"
                }
            ]
        },
        {
            "@odata.type": "#Microsoft.Skills.Text.LanguageDetectionSkill",
            "name": "#3",
            "description": null,
            "context": "/document",
            "inputs": [
                {
                    "name": "text",
                    "source": "/document/merged_content"
                }
            ],
            "outputs": [
                {
                    "name": "languageCode",
                    "targetName": "language"
                }
            ]
        },
        {
            "@odata.type": "#Microsoft.Skills.Text.MergeSkill",
            "name": "#4",
            "description": null,
            "context": "/document",
            "insertPreTag": " ",
            "insertPostTag": " ",
            "inputs": [
                {
                    "name": "text",
                    "source": "/document/content"
                },
                {
                    "name": "itemsToInsert",
                    "source": "/document/normalized_images/*/text"
                },
                {
                    "name": "offsets",
                    "source": "/document/normalized_images/*/contentOffset"
                }
            ],
            "outputs": [
                {
                    "name": "mergedText",
                    "targetName": "merged_content"
                }
            ]
        },
        {
            "@odata.type": "#Microsoft.Skills.Vision.OcrSkill",
            "name": "#5",
            "description": null,
            "context": "/document/normalized_images/*",
            "textExtractionAlgorithm": "printed",
            "lineEnding": "Space",
            "defaultLanguageCode": "en",
            "detectOrientation": true,
            "inputs": [
                {
                    "name": "image",
                    "source": "/document/normalized_images/*"
                }
            ],
            "outputs": [
                {
                    "name": "text",
                    "targetName": "text"
                },
                {
                    "name": "layoutText",
                    "targetName": "layoutText"
                }
            ]
        }
    ],
    "cognitiveServices": {
        "@odata.type": "#Microsoft.Azure.Search.CognitiveServicesByKey",
        "description": "A Cognitive Services resource in the same region as Search.",
        "key": "<COGNITIVE SERVICES All-in-ONE KEY>"
    },
    "knowledgeStore": null
}

Contoh keterampilan Shaper

Kemampuan Shaper adalah utilitas untuk bekerja dengan konten yang diperkaya yang ada alih-alih membuat konten baru yang diperkaya. Menambahkan Shaper ke set kemampuan memungkinkan Anda membuat bentuk kustom yang dapat Anda proyeksikan ke dalam penyimpanan tabel atau blob. Tanpa bentuk kustom, proyeksi terbatas untuk referensi node tunggal (satu proyeksi per output), yang tidak cocok untuk tabel. Membuat bentuk kustom menggabungkan berbagai elemen ke dalam keseluruhan logika baru yang dapat diproyeksikan sebagai satu tabel, atau dibelah dan didistribusikan di seluruh koleksi tabel.

Dalam contoh ini, bentuk kustom menggabungkan metadata blob dan entitas yang diidentifikasi serta frasa kunci. Bentuk kustom disebut projectionShape dan diindukkan di /document.

Salah satu tujuan pembentukan adalah untuk memastikan bahwa semua simpul pengayaan diekspresikan dalam JSON yang terbentuk dengan baik, yang diperlukan untuk memproyeksikan ke dalam simpanan pengetahuan. Hal ini terutama berlaku ketika pohon pengayaan mengandung simpul yang bukan JSON yang tidak terbentuk dengan baik (misalnya, ketika pengayaan diindukkan ke primitif seperti string).

Perhatikan dua simpul terakhir, KeyPhrases dan Entities. Simpul itu dikemas menjadi objek JSON yang valid dengan sourceContext. Hal ini diperlukan sebagai keyphrases dan entities merupakan pengayaan pada primitif dan perlu dikonversi ke JSON yang valid sebelum dapat diproyeksikan.

{
    "@odata.type": "#Microsoft.Skills.Util.ShaperSkill",
    "name": "ShaperForTables",
    "description": null,
    "context": "/document",
    "inputs": [
        {
            "name": "metadata_storage_content_type",
            "source": "/document/metadata_storage_content_type",
            "sourceContext": null,
            "inputs": []
        },
        {
            "name": "metadata_storage_name",
            "source": "/document/metadata_storage_name",
            "sourceContext": null,
            "inputs": []
        },
        {
            "name": "metadata_storage_path",
            "source": "/document/metadata_storage_path",
            "sourceContext": null,
            "inputs": []
        },
        {
            "name": "metadata_content_type",
            "source": "/document/metadata_content_type",
            "sourceContext": null,
            "inputs": []
        },
        {
            "name": "keyPhrases",
            "source": null,
            "sourceContext": "/document/merged_content/keyphrases/*",
            "inputs": [
                {
                    "name": "KeyPhrases",
                    "source": "/document/merged_content/keyphrases/*"
                }

            ]
        },
        {
            "name": "Entities",
            "source": null,
            "sourceContext": "/document/merged_content/entities/*",
            "inputs": [
                {
                    "name": "Entities",
                    "source": "/document/merged_content/entities/*/name"
                }

            ]
        }
    ],
    "outputs": [
        {
            "name": "output",
            "targetName": "projectionShape"
        }
    ]
}

Tambahkan Shapers ke set kemampuan

Contoh set kemampuan diperkenalkan pada awal artikel ini tidak termasuk kemampuan Shaper, tetapi kemampuan Shaper termasuk dalam set kemampuan dan sering ditempatkan menjelang akhir.

Dalam set kemampuan, kemampuan Shaper mungkin terlihat seperti ini:

    "name": "projections-demo-ss",
    "skills": [
        {
            <Shaper skill goes here>
            }
        ],
    "cognitiveServices":  "A key goes here",
    "knowledgeStore": []
}  

Memproyeksikan ke tabel

Menarik kesimpulan dari contoh di atas, ada sejumlah pengayaan dan bentuk data yang diketahui yang dapat dirujuk dalam proyeksi tabel. Di proyeksi tabel di bawah ini, tiga tabel ditentukan dengan mengatur properti tableName, source, dan generatedKeyName.

Ketiga tabel ini akan terkait melalui kunci yang dihasilkan dan oleh induk bersama /document/projectionShape.

"knowledgeStore" : {
    "storageConnectionString": "DefaultEndpointsProtocol=https;AccountName=<Acct Name>;AccountKey=<Acct Key>;",
    "projections": [
        {
            "tables": [
                {
                    "tableName": "tblDocument",
                    "generatedKeyName": "Documentid",
                    "source": "/document/projectionShape"
                },
                {
                    "tableName": "tblKeyPhrases",
                    "generatedKeyName": "KeyPhraseid",
                    "source": "/document/projectionShape/keyPhrases/*"
                },
                {
                    "tableName": "tblEntities",
                    "generatedKeyName": "Entityid",
                    "source": "/document/projectionShape/Entities/*"
                }
            ],
            "objects": [],
            "files": []
        }
    ]
}

Menguji pekerjaan Anda

Anda dapat memeriksa definisi proyeksi dengan mengikuti langkah-langkah berikut:

  1. Atur properti storageConnectionString penyimpanan pengetahuan ke string koneksi akun penyimpanan tujuan umum V2 yang valid.

  2. Perbarui rangkaian keterampilan dengan mengeluarkan permintaan PUT.

  3. Setelah memperbarui rangkaian keterampilan, jalankan pengindeks.

Anda sekarang memiliki proyeksi kerja dengan tiga tabel. Mengimpor tabel ini ke Power BI akan menghasilkan Power BI yang menemukan hubungan secara otomatis.

Sebelum beralih ke contoh berikutnya, mari kita lihat kembali aspek proyeksi tabel untuk memahami mekanika dalam membelah dan menghubungkan data.

Mengiris tabel ke beberapa tabel anak

Membelah adalah teknik yang membagi seluruh bentuk yang terkonsolidasi menjadi bagian-bagian konstituennya. Hasilnya terdiri dari tabel terpisah tetapi terkait yang dapat Anda kerjakan secara sendiri-sendiri.

Dalam contoh, projectionShape adalah bentuk terkonsolidasi (atau simpul pengayaan). Dalam definisi proyeksi, projectionShape diiris menjadi tabel-tabel tambahan, yang memungkinkan Anda menarik bagian dari bentuk tersebut, keyPhrases dan Entities. Di Power BI, hal ini berguna karena beberapa entitas dan keyPhrases dikaitkan dengan setiap dokumen, dan Anda akan mendapatkan lebih banyak wawasan jika Anda bisa melihat entitas dan keyPhrases sebagai data yang sudah terkategorikan.

Mengiris secara implisit menghasilkan hubungan antara tabel induk dan anak, menggunakan generatedKeyName dalam tabel induk untuk membuat kolom dengan nama yang sama dalam tabel anak.

Penamaan hubungan

Properti generatedKeyName dan referenceKeyName digunakan untuk menghubungkan data lintas tabel atau bahkan di seluruh jenis proyeksi. Setiap baris dalam tabel anak memiliki properti yang menunjuk kembali ke induk. Nama kolom atau properti dalam anak adalah referenceKeyName dari induknya. Ketika referenceKeyName tidak disediakan, layanan men-default-kan ke generatedKeyName dari induknya.

Power BI mengandalkan tombol yang dihasilkan ini untuk menemukan hubungan dalam tabel. Jika Anda memerlukan kolom dalam tabel anak bernama berbeda, atur properti referenceKeyName di tabel induk. Salah satu contohnya adalah mengatur generatedKeyName sebagai ID pada tabel tbIDocument dan referenceKeyName sebagai DocumentID. Hal ini akan menghasilkan kolom dalam tabel tbIEntities dan tbIKeyPhrases yang berisi ID dokumen bernama DocumentID.

Memproyeksikan dokumen blob

Proyeksi objek adalah representasi JSON dari pohon pengayaan yang dapat bersumber dari node apa pun. Dibandingkan dengan proyeksi tabel, proyeksi objek lebih mudah untuk didefinisikan dan digunakan saat memproyeksikan seluruh dokumen. Proyeksi objek dibatasi pada proyeksi tunggal dalam wadah dan tidak dapat diiris.

Untuk menentukan proyeksi objek, gunakan array objects dalam properti proyeksi.

Sumbernya adalah jalur ke simpul pohon pengayaan yang merupakan akar proyeksi. Meskipun tidak diperlukan, jalur simpul biasanya merupakan output dari kemampuan Shaper. Hal ini karena sebagian besar kemampuan tidak menghasilkan objek JSON yang valid sendiri, artinya beberapa bentuk pembentukan diperlukan. Dalam banyak kasus, kemampuan Pembentuk yang sama yang membuat proyeksi tabel dapat digunakan untuk menghasilkan proyeksi objek. Atau, sumber juga dapat diatur ke simpul dengan pembentukan sebaris untuk menyediakan struktur.

Tujuannya selalu kontainer blob.

Contoh berikut memproyeksikan dokumen hotel individu, satu dokumen hotel per blob, ke dalam kontainer yang disebut hotels.

"knowledgeStore": {
  "storageConnectionString": "an Azure storage connection string",
  "projections" : [
    {
      "tables": [ ]
    },
    {
      "objects": [
        {
        "storageContainer": "hotels",
        "source": "/document/objectprojection",
        }
      ]
    },
    {
        "files": [ ]
    }
  ]
}

Sumbernya adalah output dari kemampuan Shaper, bernama "objectprojection". Setiap blob akan memiliki representasi JSON dari setiap input bidang.

    {
      "@odata.type": "#Microsoft.Skills.Util.ShaperSkill",
      "name": "#3",
      "description": null,
      "context": "/document",
      "inputs": [
        {
          "name": "HotelId",
          "source": "/document/HotelId"
        },
        {
          "name": "HotelName",
          "source": "/document/HotelName"
        },
        {
          "name": "Category",
          "source": "/document/Category"
        },
        {
          "name": "keyPhrases",
          "source": "/document/HotelId/keyphrases/*"
        },
      ],
      "outputs": [
        {
          "name": "output",
          "targetName": "objectprojection"
        }
      ]
    }

Memproyeksikan file gambar

Proyeksi file selalu biner, gambar dinormalisasi, di mana normalisasi mengacu pada ukuran ulang potensial dan rotasi untuk digunakan dalam eksekusi set kemampuan. Proyeksi file, serupa dengan proyeksi objek, dibuat sebagai blob di Azure Storage, dan berisi gambar.

Untuk menentukan proyeksi file, gunakan array files dalam properti proyeksi.

Sumbernya selalu /document/normalized_images/*. Proyeksi file hanya bertindak pada kumpulan normalized_images. Baik pengindeks maupun set kemampuan tidak akan melewati gambar asli yang tidak dinormalisasi.

Tujuannya selalu kontainer blob, dengan awalan folder dari nilai yang dikodekan base64 dari ID dokumen. Proyeksi file tidak dapat berbagi kontainer yang sama dengan proyeksi objek dan perlu diproyeksikan ke dalam kontainer yang berbeda.

Contoh berikut memproyeksikan semua gambar yang dinormalisasi yang diekstraksi dari simpul dokumen pada dokumen yang diperkaya ke dalam kontainer yang disebut myImages.

"knowledgeStore" : {
    "storageConnectionString": "DefaultEndpointsProtocol=https;AccountName=<Acct Name>;AccountKey=<Acct Key>;",
    "projections": [
        {
            "tables": [ ],
            "objects": [ ],
            "files": [
                {
                    "storageContainer": "myImages",
                    "source": "/document/normalized_images/*"
                }
            ]
        }
    ]
}

Memproyeksikan ke beberapa tipe

Skenario yang lebih kompleks mungkin mengharuskan Anda memproyeksikan konten di seluruh tipe proyeksi. Misalnya, memproyeksikan frasa kunci dan entitas ke tabel, menyimpan hasil OCR teks dan teks tata letak sebagai objek, kemudian memproyeksikan gambar sebagai file.

Langkah-langkah untuk beberapa jenis proyeksi:

  1. Membuat tabel dengan baris untuk setiap dokumen.
  2. Buat tabel yang terkait dengan tabel dokumen dengan setiap frasa kunci yang diidentifikasi sebagai baris dalam tabel ini.
  3. Buat tabel yang terkait dengan tabel dokumen dengan setiap entitas yang diidentifikasi sebagai baris dalam tabel ini.
  4. Buat proyeksi objek dengan teks tata letak untuk setiap gambar.
  5. Membuat proyeksi file, memproyeksikan setiap gambar yang diekstrak.
  6. Buat tabel referensi silang yang berisi referensi ke tabel dokumen, proyeksi objek dengan teks tata letak, dan proyeksi file.

Membentuk data untuk proyeksi silang

Untuk mendapatkan bentuk yang diperlukan untuk proyeksi ini, mulailah dengan menambahkan keterampilan Shaper baru yang membuat objek berbentuk yang disebut crossProjection.

{
    "@odata.type": "#Microsoft.Skills.Util.ShaperSkill",
    "name": "ShaperForCrossProjection",
    "description": null,
    "context": "/document",
    "inputs": [
        {
            "name": "metadata_storage_name",
            "source": "/document/metadata_storage_name",
            "sourceContext": null,
            "inputs": []
        },
        {
            "name": "keyPhrases",
            "source": null,
            "sourceContext": "/document/merged_content/keyphrases/*",
            "inputs": [
                {
                    "name": "KeyPhrases",
                    "source": "/document/merged_content/keyphrases/*"
                }

            ]
        },
        {
            "name": "entities",
            "source": null,
            "sourceContext": "/document/merged_content/entities/*",
            "inputs": [
                {
                    "name": "Entities",
                    "source": "/document/merged_content/entities/*/name"
                }

            ]
        },
        {
            "name": "images",
            "source": null,
            "sourceContext": "/document/normalized_images/*",
            "inputs": [
                {
                    "name": "image",
                    "source": "/document/normalized_images/*"
                },
                {
                    "name": "layoutText",
                    "source": "/document/normalized_images/*/layoutText"
                },
                {
                    "name": "ocrText",
                    "source": "/document/normalized_images/*/text"
                }
                ]
        }
 
    ],
    "outputs": [
        {
            "name": "output",
            "targetName": "crossProjection"
        }
    ]
}

Menentukan proyeksi tabel, objek, dan file

Dari objek crossProjection terkonsolidasi, iris objek menjadi beberapa tabel, tangkap output OCR sebagai blob, lalu simpan gambar sebagai file (juga dalam penyimpanan Blob).

"knowledgeStore" : {
    "storageConnectionString": "DefaultEndpointsProtocol=https;AccountName=<Acct Name>;AccountKey=<Acct Key>;",
    "projections": [
            {
            "tables": [
                {
                    "tableName": "crossDocument",
                    "generatedKeyName": "Id",
                    "source": "/document/crossProjection"
                },
                {
                    "tableName": "crossEntities",
                    "generatedKeyName": "EntityId",
                    "source": "/document/crossProjection/entities/*"
                },
                {
                    "tableName": "crossKeyPhrases",
                    "generatedKeyName": "KeyPhraseId",
                    "source": "/document/crossProjection/keyPhrases/*"
                },
                {
                    "tableName": "crossReference",
                    "generatedKeyName": "CrossId",
                    "source": "/document/crossProjection/images/*"
                }
                    
            ],
            "objects": [
                {
                    "storageContainer": "crossobject",
                    "generatedKeyName": "crosslayout",
                    "source": null,
                    "sourceContext": "/document/crossProjection/images/*/layoutText",
                    "inputs": [
                        {
                            "name": "OcrLayoutText",
                            "source": "/document/crossProjection/images/*/layoutText"
                        }
                    ]
                }
            ],
            "files": [
                {
                    "storageContainer": "crossimages",
                    "generatedKeyName": "crossimages",
                    "source": "/document/crossProjection/images/*/image"
                }
            ]
        }
    ]
}

Proyeksi objek memerlukan nama kontainer untuk masing-masing proyeksi. Proyeksi objek dan proyeksi file tidak dapat berbagi kontainer.

Hubungan antara proyeksi tabel, objek, dan file

Contoh ini juga menyoroti fitur lain dari proyeksi. Dengan mendefinisikan beberapa jenis proyeksi dalam objek proyeksi yang sama, ada hubungan yang dinyatakan dalam dan di seluruh tipe yang berbeda (tabel, objek, file). Ini memungkinkan Anda memulai dengan baris tabel untuk dokumen dan menemukan semua teks OCR untuk gambar dalam dokumen tersebut dalam proyeksi objek.

Jika Anda tidak ingin data saling terkait, tentukan proyeksi dalam objek proyeksi yang berbeda. Misalnya, cuplikan berikut akan mengakibatkan tabel terkait, tetapi tanpa hubungan antara tabel dan proyeksi objek (teks OCR).

Grup proyeksi berguna saat Anda ingin memproyeksikan data yang sama dalam berbagai bentuk untuk kebutuhan yang berbeda. Misalnya, grup proyeksi untuk dasbor Power BI, dan grup proyeksi lain untuk menangkap data yang digunakan untuk melatih model pembelajaran mesin yang dikemas dengan keterampilan kustom.

Saat membangun proyeksi dari berbagai jenis, proyeksi file dan objek dihasilkan terlebih dahulu, dan jalur ditambahkan ke tabel.

"knowledgeStore" : {
    "storageConnectionString": "DefaultEndpointsProtocol=https;AccountName=<Acct Name>;AccountKey=<Acct Key>;",
    "projections": [
        {
            "tables": [
                {
                    "tableName": "unrelatedDocument",
                    "generatedKeyName": "Documentid",
                    "source": "/document/projectionShape"
                },
                {
                    "tableName": "unrelatedKeyPhrases",
                    "generatedKeyName": "KeyPhraseid",
                    "source": "/document/projectionShape/keyPhrases"
                }
            ],
            "objects": [
                
            ],
            "files": []
        }, 
        {
            "tables": [],
            "objects": [
                {
                    "storageContainer": "unrelatedocrtext",
                    "source": null,
                    "sourceContext": "/document/normalized_images/*/text",
                    "inputs": [
                        {
                            "name": "ocrText",
                            "source": "/document/normalized_images/*/text"
                        }
                    ]
                },
                {
                    "storageContainer": "unrelatedocrlayout",
                    "source": null,
                    "sourceContext": "/document/normalized_images/*/layoutText",
                    "inputs": [
                        {
                            "name": "ocrLayoutText",
                            "source": "/document/normalized_images/*/layoutText"
                        }
                    ]
                }
            ],
            "files": []
        }
    ]
}

Langkah berikutnya

Contoh dalam artikel ini menunjukkan pola umum tentang cara membuat proyeksi. Sekarang setelah Anda memiliki pemahaman yang baik tentang konsep, Anda lebih siap untuk membangun proyeksi untuk skenario spesifik Anda.