6

私は次のようなドキュメント構造を持っています:

Employer => Positions => RequiredSkills

雇用主にはポジションのコレクションがありますポジション
にはRequiredSkillのコレクションがあります。
必要なスキルは、スキル(文字列)と習熟度(列挙型)で構成されます。

動的インデックスを使用すると、会社は正常に返されるように見えますが、インデックスを使用してMVCビューモデルにデータを入力し、UIに戻りたいと思います。

私はレイヴンに本当に慣れていないので、愚かな/不必要なことをしてしまったことをお詫びします!

私は次のマッピングを持っています:

public class PositionSearch : AbstractIndexCreationTask<Employer>
    {
        public PositionSearch()
        {
            Map = employers =>
                  from employer in employers
                  from position in employer.Positions
                  select new
                      {
                          EmployerId = employer.Id,
                          EmployerName = employer.Name,
                          PositionId = position.Id,
                          PositionTitle = position.Title,
                          position.Location,
                          position.Description,
                          RequiredSkills = position.RequiredSkills
                      };

            StoreAllFields(FieldStorage.Yes);

            Index("RequiredSkills_Skill", FieldIndexing.Analyzed);
        }
    }

ただし、次のクエリを実行しようとすると、次のようになります。

var results = session.Query<PositionSearchResultModel, PositionSearch>()
    .Customize(x => x.WaitForNonStaleResults())
    .Where(x=>x.RequiredSkills.Any(y=>y.Skill == "SkillName"))
    .ProjectFromIndexFieldsInto<PositionSearchResultModel>()
    .ToList();

次のエラーが発生します。

System.ArgumentException:
    The field 'RequiredSkills_Skill' is not indexed,
    cannot query on fields that are not indexed

誰かが私が間違っていることを確認したり、私のために別のアプローチを提案したりできますか?

ありがとう、

ジェームズ

ビューモデルを更新する-ありがとう:

public class PositionSearchResultModel
{
    public PositionSearchResultModel()
    {
        RequiredSkills = new HashSet<SkillProficiency>();
    }

    public string EmployerId { get; set; }
    public string EmployerName { get; set; }
    public string PositionId { get; set; }
    public string PositionTitle { get; set; }
    public string Location { get; set; }
    public string Description { get; set; }
    public ICollection<SkillProficiency> RequiredSkills { get; set; }
 }
4

1 に答える 1

10

スキル名に対して分析検索を実行するため、スキル名を個別のインデックスエントリとして分離する必要があります。

public class PositionSearch
    : AbstractIndexCreationTask<Employer, PositionSearchResultModel>
{
    public PositionSearch()
    {
        Map = employers =>
                from employer in employers
                from position in employer.Positions
                select new
                {
                    EmployerId = employer.Id,
                    EmployerName = employer.Name,
                    PositionId = position.Id,
                    PositionTitle = position.Title,
                    position.Location,
                    position.Description,
                    position.RequiredSkills,

                    // Isolate the search property into it's own value
                    SkillsSearch = position.RequiredSkills.Select(x => x.Skill)
                };

        // you could store all fields if you wanted, but the search field
        // doesn't need to be stored so that would be wasteful.
        Store(x => x.PositionId, FieldStorage.Yes);
        Store(x => x.PositionTitle, FieldStorage.Yes);
        Store(x => x.Location, FieldStorage.Yes);
        Store(x => x.Description, FieldStorage.Yes);
        Store(x => x.RequiredSkills, FieldStorage.Yes);

        // Any field you are going to use .Search() on should be analyzed.
        Index(x => x.SkillsSearch, FieldIndexing.Analyzed);
    }
}

インデックスの結果として投影を指定したことに注意してください。これは糖衣構文です。省略しても間違いありませんが、文字列を使用して検索フィールドを指定する必要があります。

また、検索フィールドを結果クラスに追加する必要があります

public string[] SkillsSearch { get; set; }

それがどんなタイプであるかは本当に問題ではありません。文字列配列またはコレクションは問題なく機能します。関連するのは名前だけなので、文字列またはオブジェクトだけを使用することもできます。

このインデックスに対してクエリを実行するときは.Search()、次のようなメソッドを使用します。

var results = session.Query<PositionSearchResultModel, PositionSearch>()
    .Customize(x => x.WaitForNonStaleResults())  // only use this in testing
    .Search(x=> x.SkillsSearch, "SkillName")
    .ProjectFromIndexFieldsInto<PositionSearchResultModel>()  // AsProjection would also work
    .ToList();

非常に多くのフィールドを格納する必要がある唯一の理由は、それらを投影するためであることに注意してください。ポジションを独自のドキュメントに分割すると、インデックスがはるかに小さくなり、投影することがはるかに少なくなります。投影するとき、元のドキュメントのすべてのフィールドはすでにそこにあり、インデックスにコピーする必要はなく、ドキュメントストアから直接取得されることに注意してください。したがって、元のドキュメントが目的の結果とより厳密に一致する場合は、実行する作業が少なくなります。

于 2013-02-12T16:15:51.090 に答える