次の方法で共有


SharePoint Server 2010 の管理されたメタデータの移行

概要:  Managed Metadata Service アプリケーションを使用して、管理されたメタデータを Microsoft SharePoint Server 2010 の開発、テスト、および運用の各環境間で移行する方法について説明します。

最終更新日: 2011年5月23日

適用対象: Business Connectivity Services | Open XML | SharePoint Designer 2010 | SharePoint Foundation 2010 | SharePoint Online | SharePoint Server 2010 | Visual Studio

この記事の内容
SharePoint Server 2010 での Managed Metadata Service アプリケーションの概要
用語ストアの管理ツールを使用した分類の作成と移行
SharePoint Server 2010 でのエンタープライズ コンテンツ タイプの作成と移行
まとめ
その他の技術情報

提供元:  Scot Hillier (SharePoint MVP)、Technical Solutions, LLC (英語)

目次

  • SharePoint Server 2010 での Managed Metadata Service アプリケーションの概要

  • 用語ストアの管理ツールを使用した分類の作成と移行

  • SharePoint Server 2010 でのエンタープライズ コンテンツ タイプの作成と移行

  • まとめ

  • その他の技術情報

SharePoint Server 2010 での Managed Metadata Service アプリケーションの概要

Managed Metadata Service (MMS) は、Microsoft SharePoint Server 2010 で利用できるいくつかのサービス アプリケーションの 1 つです。MMS は、分類サービスおよびコンテンツ タイプの発行サービスの 2 つの重要なサービスを提供します。分類サービスでは、中央管理される用語 (用語セットと呼ばれる) の階層コレクションの作成と管理ができます。この用語は、SharePoint サイトでアイテムの属性として使用できます。用語セットは、サイト コレクションと Web アプリケーション全体で共有できます。コンテンツ タイプの発行サービスでも、コンテンツ タイプをサイト コレクションと Web アプリケーション全体で共有できます。MMS は、図 1 のように、サーバーの全体管理サイトを使用して利用できます。

図 1. Managed Metadata Service アプリケーションの管理

Managed Metadata Service の管理

用語セットの作成と管理は、用語ストアの管理ツールを使用して行うことができます。用語分類担当者、管理者、または分類を管理する他のユーザーは、このツールを使用して、用語セットと用語セットに含まれる用語の作成、インポート、および管理ができます。用語ストアの管理ツールには、図 2 のように、すべてのグローバル用語セットが表示されると共に、ツールにアクセスした場所のサイト コレクションで利用可能なあらゆるローカル用語セットが表示されます。

図 2. 用語ストアの管理ツール

用語ストアの管理ツール

ファーム管理者は、サイト コレクションをコンテンツ タイプの発行用のハブとして構成することで、コンテンツ タイプの発行を構成します。MMS の作成と構成が完了すると、ファーム管理者は MMS を発行します。ファーム管理者は、発行された URL を使用して他の Web アプリケーションをこの MMS に接続し、そのコンテンツ タイプを購読できます。

用語ストアの管理ツールを使用した分類の作成と移行

用語ストアの管理ツールで分類を作成します。分類は、サーバーの全体管理サイトまたはサイト コレクション レベルで作成します。分類は、複数の用語を含む用語セットとして作成されます。用語には、最大 7 レベルまでネストされた子の用語を追加できます。

SharePoint Server 2010 では、管理されたメタデータの列に分類からの用語が表示されます。管理されたメタデータの列のフィールドの値は、分類から選択されます。管理されたメタデータの列では、分類の値を表示、操作、および選択するための特別なインターフェイスが使用されます (図 3 を参照)。分類は、グローバル グループか、サイト コレクションに固有となるグループに作成できます。

図 3. 管理されたメタデータの列の操作

Managed Metadata 列の操作

多くの場合、分類は、多くの SharePoint 成果物と同様に、より大きな機能の一部として開発環境で作成されます。初期分類が作成された後、その初期分類をテスト環境、ステージング環境、または運用環境に移行することが必要になる場合があります。移行が必要な場合、分類を 1 つの環境からエクスポートして、別の環境にインポートする必要があります。用語ストアの管理ツールでは、分類のインポートはサポートされますが、分類のエクスポートはサポートされません。この理由のため、分類の移行をサポートするユーザー設定コードを使用する必要があります。

管理されたメタデータの入力ファイル形式

MMS への分類のインポートは、カンマ区切りファイル形式 (.csv ファイル) を使用することでサポートされます。このファイル形式は、用語セットおよび含まれる用語の階層を定義する特定の構造を持ちます。用語ストアの管理ツールで [サンプル インポート ファイルの表示] を選択することで、図 4 のようなサンプルのインポート ファイルを表示できます。

図 4. サンプル インポート ファイル

サンプル インポート ファイル

ファイルを適切な形式で作成した後、そのファイルを MMS にインポートできます。図 5 のように、インポート コマンドは、用語ストアの管理ツール内のすべてのグループに関連付けられたショートカット メニューから利用できます。

図 5. 分類のインポート

分類のインポート

用語ストアの管理ツールを使用して分類アイテムをインポートするのに加えて、開発者は分類オブジェクト モデルを使用してアイテムをインポートできます。分類オブジェクト モデルは、参照が Microsoft.SharePoint.Taxonomy.dll アセンブリに設定されている場合に使用できます。このアセンブリは、SharePoint Server 2010 システム ディレクトリの ISAPI フォルダーにあります。ImportManager クラスには、分類のインポートに使用できる ImportTermSet() メソッドがあります。以下のコードは、分類が含まれる .csv ファイルをプログラムによってインポートする方法を示しています。このコードでは 3 つの引数が渡されることが期待されます。それらは、サイトコレクションの URL、用語が含まれる .csv ファイルへのファイル パス、および新しい用語セットの作成先であるグループの名前です。

static void Main(string[] args)
{
    try
    {

        if (args.Length != 3)
            throw new Exception(
        "Usage: ImportTermSet SiteCollectionUrl FilePath GroupName");

        string siteCollectionUrl = args[0];
        string filePath = args[1];
        string groupName = args[2];

        StreamReader reader = File.OpenText(filePath);
        using (SPSite (siteCollectionUrl))
        {
            TaxonomySession session =
              new TaxonomySession(siteCollection);
            TermStore store = session.TermStores[0];
            Group group = store.Groups.Where(
              g => g.Name == groupName).FirstOrDefault();
            if (group == null)
                group = store.CreateGroup(groupName);
            ImportManager manager = store.GetImportManager();
            bool allTermsAdded = false;
            string errorMessage = string.Empty;
            manager.ImportTermSet(group, reader,
                    out allTermsAdded, out errorMessage);

            if (errorMessage.Length > 0)
                throw new Exception(errorMessage);
        }

        Console.WriteLine("Import complete!");
    }
    catch (Exception x)
    {
        Console.WriteLine(x.Message);
    }
}

SharePoint Server 2010 からの分類のエクスポート

分類の移行における課題は、用語ストアの管理ツールでエクスポート機能が公開されていないことです。したがって、エクスポートは、ユーザー設定コードのみを使用して行う必要があります。分類オブジェクト モデルでは、TermSet クラスで Export() メソッドが公開されています。ただし、このメソッドは実装されていません。結果として、ユーザー設定コードを記述し、各種用語を TermSet オブジェクトとして列挙して、必要な .csv ファイルに書き込む必要があります。以下のコードは、分類を .csv ファイルにエクスポートするための完全なコンソール アプリケーションを示しています。このコードでは、2 つの引数が渡されることが期待されます。それらは、サイト コレクションの URL、およびエクスポートする用語セットを識別するラベルです。

static void Main(string[] args)
{
  try
  {

    if (args.Length != 2)
      throw new Exception(
        "Usage: ExportTermSet SiteCollectionUrl RequiredTermLabel");

    string siteCollectionUrl = args[0];
    string requiredTermLabel = args[1];

    using (SPSite siteCollection = new SPSite(args[0]))
    {
      TaxonomySession session = new TaxonomySession(siteCollection);
      string[] requiredTermLabels = { requiredTermLabel };
      TermSetCollection termSets =
        session.GetTermSets(requiredTermLabels);

        if (termSets.Count > 0)
        {
          foreach (TermSet termSet in termSets)
          {
              // termSet.Export(); is NOT IMPLEMENTED. 

              StreamWriter writer =
                File.CreateText(termSet.Name + ".csv");
              writer.AutoFlush = true;
              List<string> headerNameData = new List<string>()
              {
                  "\"Term Set Name\"",
                  "\"Term Set Description\"",
                  "\"LCID\"",
                  "\"Available for Tagging\"",
                  "\"Term Description\"",
                  "\"Level 1 Term\"",
                  "\"Level 2 Term\"",
                  "\"Level 3 Term\"",
                  "\"Level 4 Term\"",
                  "\"Level 5 Term\"",
                  "\"Level 6 Term\"",
                  "\"Level 7 Term\""
              };
              List<string> headerValueData = new List<string>()
              {
                  termSet.Name,
                  termSet.Description,
                  null,
                  termSet.IsAvailableForTagging.ToString(),
                  null,null,null,null,null,null,null,null
              };

              writer.WriteLine(headerNameData.GetCSVFormat());
              writer.WriteLine(headerValueData.GetCSVFormat());
              foreach (Term level1Term in termSet.Terms)
              {
                  List<string> nameData =
                    new List<string>() { level1Term.Name };
                  List<string> termData = new List<string>(){
                      null,null,null,
                      level1Term.IsAvailableForTagging.ToString(),
                      level1Term.GetDescription(),
                      nameData.GetCSVFormat(),
                      null,null,null,null,null,null};

                  writer.WriteLine(termData.GetCSVFormat());

                  WriteSubTerms(level1Term, nameData, writer);

              }

              writer.Close();
          }
      }
      else
      {
          throw new Exception(
            "No term set named'" + requiredTermLabel + "'found.");
      }
  }

    Console.WriteLine("Export complete!");
  }
  catch (Exception x)
  {
    Console.WriteLine(x.Message);
  }
}

static void WriteSubTerms(Term ParentTerm, List<string> ParentNameData, StreamWriter Writer)
{
  foreach (Term levelTerm in ParentTerm.Terms)
  {
    List<string> nameData = new List<string>();
    nameData.AddRange(ParentNameData);
    nameData.Add(levelTerm.Name);

    List<string> termData = new List<string>(){
                 null,
                 null,
                 null,
                 levelTerm.IsAvailableForTagging.ToString(),
                 levelTerm.GetDescription(),
                 nameData.GetCSVFormat()};
    for (int i = 0; i < 7 - ParentNameData.Count; i++)
    {
        termData.Add(null);
    }

    Writer.WriteLine(termData.GetCSVFormat());

    WriteSubTerms(levelTerm, nameData, Writer);

  }
}

管理されたメタデータのフィールドの移行

分類を伴う開発プロセスの一環として、管理されたメタデータのフィールドを使用する新しいリストが作成される場合があります。リストに関連付けられた分類と同様に、リストも開発環境からテスト環境、ステージング環境、または運用環境に移行することが必要になる場合があります。ただし、そのようなリストの移行では、グローバル一意識別子 (GUID) の問題が発生します。

MMS は、TermSet オブジェクトおよびそのオブジェクトに含まれる Term オブジェクトの ID として GUID を割り当てます。SharePoint Server 2010 は、用語が作成またはインポートされるときに GUID 値を割り当てます。分類が 1 つの環境からエクスポートされ、別の環境にインポートされた場合、システムは新しい GUID 値を割り当てます。管理されたメタデータの列がリストで使用されている場合、そのリストでは、関連付けられた用語セットと選択された用語を識別するのに GUID 値が使用されます。そのようなリストのインスタンスを新しい環境に移行し、そこで分類の GUID 値を変更した場合、その列は機能しなくなり、その列を新しい環境で再作成する必要が生じます。

SharePoint Server 2010 でのエンタープライズ コンテンツ タイプの作成と移行

エンタープライズ コンテンツ タイプは、購読元のサイト コレクション内で使用するためにコンテンツ タイプ ハブに特別に割り当てられたコンテンツ タイプです。エンタープライズ コンテンツ タイプは、ハブのコンテンツ タイプ ギャラリー内のブラウザーで直接作成するか、ハブにインストールされる機能として作成することができます。

環境間で移行可能なエンタープライズ コンテンツ タイプの作成に関心のある開発者にとって、適切な方法は、Microsoft Visual Studio 2010 を使用してエンタープライズ コンテンツ タイプを機能として作成することです。これは、SharePoint ソリューション パッケージ (.wsp) ファイル内にパッケージ化されるコンテンツ タイプを作成するという考え方であり、これにより、1 つの環境内のハブから別の環境内のハブにコンテンツ タイプを簡単に移動できます。ただし、開発者は、コンテンツ タイプ ハブでこの機能が適切に動作するように機能を作成する必要があります。

多くの SharePoint プロジェクトの場合と同様に、コンテンツ タイプを宣言的に作成するか、プログラムによって作成できます。コンテンツ タイプを宣言的に作成するには、使用する列とフォームを指定する Elements.xml ファイルを作成します。以下の例は、宣言的に定義されるコンテンツ タイプを示しています。

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="https://schemas.microsoft.com/sharepoint/">
  <Field
    ID="{D713DCD2-6626-47a1-A23F-3C24CD66A3F9}" 
    Name="Amount"
    DisplayName="Amount"
    Type="Currency"
    Decimals="2"
    Min="0" 
    Group="Financial Columns">
  </Field>
  <ContentType
    ID="0x01010012841A8869DB425cB829C3875EC558CE"
    Name="Financial Document"
    Description="Base financial document"
    Version="0"
    Group="Financial Document Types" >
    <FieldRefs>
      <FieldRef 
        ID="{D713DCD2-6626-47a1-A23F-3C24CD66A3F9}" 
        Name="Amount" DisplayName="Amount" />
    </FieldRefs>
  </ContentType>
</Elements>

宣言的なコンテンツ タイプの問題は、それらがコンテンツ タイプ ハブで適切に動作しないことです。理想的な方法は、コンテンツ タイプが含まれる機能をハブにインストールし、そのコンテンツ タイプを購読元のサイト コレクションに発行することです。ただし、コンテンツ タイプが宣言的に作成されている場合、この操作は失敗します。回避策は、コンテンツ タイプをプログラムによって作成することです。以下のコードは、フィーチャー レシーバーを使用してエンタープライズ コンテンツ タイプをプログラムによって作成する方法を示しています。

SPSite siteCollection = (SPSite)properties.Feature.Parent;
SPWeb site = siteCollection.OpenWeb();

/* CREATE SITE COLUMN */

//The amount.
string amountFieldName = site.Fields.Add("Amount", SPFieldType.Currency, false);
SPFieldCurrency amountField = (SPFieldCurrency)site.Fields.GetFieldByInternalName(amountFieldName);
amountField.Group = "Financial Columns";
amountField.Update();

/* CREATE CONTENT TYPE */

//Get the parent document content type.
SPContentTypeId documentCTypeId = new SPContentTypeId(documentId);
SPContentType documentCType = site.AvailableContentTypes[documentCTypeId];

//Get the financial document content type.
SPContentType financialDocumentCType = new SPContentType(documentCType, site.ContentTypes, "Financial Document");
financialDocumentCType.Group = "Financial Content Types";
site.ContentTypes.Add(financialDocumentCType);
financialDocumentCType = site.ContentTypes[financialDocumentCType.Id];

/* ADD COLUMN TO CONTENT TYPE */

//The amount column.
SPFieldLink amountLink = new SPFieldLink(amountField);
financialDocumentCType.FieldLinks.Add(amountLink);
financialDocumentCType.Update(true);

まとめ

SharePoint Server 2010 の Managed Metadata Service アプリケーションでは、エンタープライズ コンテンツ管理をサポートする機能が提供されます。Managed Metadata Service アプリケーションの機能を使用するソリューションを作成する場合は、環境間で移行するときにメタデータで何が起きるかを検討してください。SharePoint Server 2010 には、分類とエンタープライズ コンテンツ タイプに影響するいくつかの制限がありますが、十分な回避策が用意されており、それを使用して SharePoint Server 2010 ソリューションを厳密なソフトウェア開発ライフ サイクルに加えることができます。

その他の技術情報

詳細については、次のリソースを参照してください。