6

これはWebデータベースの重要なポイントであると認識しているため、この質問はマスターデータベースに当てはまります...

Sitecore6.4.1で次のようにカスタムインデックスを設定しています。

<index id="search_content_US" type="Sitecore.Search.Index, Sitecore.Kernel">
    <param desc="name">$(id)</param>
    <param desc="folder">_search_content_US</param>
    <Analyzer ref="search/analyzer" />
    <locations hint="list:AddCrawler">
        <search_content_home type="Sitecore.Search.Crawlers.DatabaseCrawler, Sitecore.Kernel">
            <Database>master</Database>
            <Root>/sitecore/content/usa home</Root>
            <Tags>home content</Tags>
        </search_content_home>
    </locations>
</index>

SortableIndexSearchContextこのようにインデックスをクエリします(この回答からtechphoria414を使用しています:新しいSitecore.Search APIを使用して並べ替え/フィルタリングする方法):

private SearchHits GetSearchResults(SortableIndexSearchContext searchContext, string searchTerm)
    {
        CombinedQuery query = new CombinedQuery();
        query.Add(new FullTextQuery(searchTerm), QueryOccurance.Must);
        return searchContext.Search(query, Sort.RELEVANCE);
    }

...

SearchHits hits = GetSearchResults(searchContext, searchTerm);

hits私のインデックスからの検索ヒットのコレクションです。繰り返してみるとhits、Sitecoreには、アイテムのバージョンごとに1つずつ、同じアイテムの重複が多数あることがわかります。

次に、次のようにして:を取得しますSearchResultCollection

SearchResultCollection results = hits.FetchResults(0, hits.Length);

これにより、すべての複製が1つのSearchResultオブジェクトに結合されます。このオブジェクトは、特定のアイテムの1つのバージョンを表し、他のすべてのアイテムバージョンを表すのSubResultsコレクションであるというプロパティがあります。SearchResult

これが私の問題です:

で表されるアイテムのバージョンは、現在公開されているアイテムのバージョンでSearchResultはありません。ランダムに選択されたバージョンのようです(インデックスで最初にヒットした検索方法のいずれか)。ただし、最新バージョンSubResultsコレクションに含まれています。

例えば:

SearchResult
 |
 |- Version 8 // main result
 ...
 |- SubResults
      |
      |- Version 9 // latest version
      |- Version 3
      |- Version 5
      ... // all versions in random order

マスターデータベースでこれが発生しないようにするにはどうすればよいですか?Luceneが古いバージョンのアイテムにインデックスを付けるのを防ぐか、結果セットを操作して最新バージョンをSubResults

余談ですが、Luceneが古いバージョンのアイテムのインデックスを作成するのはなぜですか?古いバージョンが表示されないので、これはあなたのウェブサイトのコンテンツを検索するのに無意味ですか?

4

6 に答える 6

10

以下をオーバーライドするカスタムクローラーを実装できます。

public class IndexCrawler : DatabaseCrawler
{
    protected override void IndexVersion(Item item, Item latestVersion, Sitecore.Search.IndexUpdateContext context)
    {
        if (item.Versions.Count > 0 && item.Version.Number != latestVersion.Version.Number)
            return;

        base.IndexVersion(item, latestVersion, context);
    }
}

これにより、アイテムの最新バージョンのみがインデックスに登録されるため、そのインデックスからプルされる唯一のアイテムになります。

もちろん、インデックスの正しいタイプを設定するには、構成ファイルを更新する必要があります

于 2013-02-06T17:11:54.917 に答える
8

Sitecore 7では、最新バージョンの「1」を含むフィールド_latestversionがインデックスに追加されました(他のバージョンの値は空です)。

于 2013-08-19T13:06:35.870 に答える
7

マスターではなくWebデータベースでLuceneを検索する場合は、最後に公開されたバージョンのみをインデックスに登録する必要があります。

<Database>web</Database>
于 2012-12-04T11:51:07.793 に答える
2

調整されたソートメカニズムを使用してyetimanが提供するソリューションは興味深いアプローチですが、2つのバージョンのLucene結果スコアが異なる傾向がある場合は完全なソリューションを提供しません。たとえば、スコア0.7のv1とスコア0.5のv2から、彼のソリューションはアイテムの最初のバージョンを返します。(少なくとも私のテストでは。)

さらに掘り下げた後、最も明白な解決策は、独自の実装Sitecore.Pipelines.Search.SearchSystemIndexを行い、デフォルトの代わりにそれを使用することです。ILSpyなどを使用してそのコードを逆コンパイルすると、Processメソッドの下部に次のように表示されます。

foreach (SearchResult current in searchHits.FetchResults(0, searchHits.Length)){
  // ...
}

そのようなものはそれぞれSearchResult実際にはグループ化されており、Luceneから返された最初の結果(したがって、スコアが最も高いもの)が主な結果になります。同じアイテムの他のバージョン(および他の言語)のヒットにはSubresults、各インスタンスのプロパティからアクセスできます。またはnull何もない場合。

要件に応じて、クラスのこの部分をニーズに合わせて調整できます。

于 2013-01-04T07:46:55.067 に答える
0

正確な答えはわかりませんが(Luceneがマスターデータベースで古いバージョンのインデックスを作成するのをやめるため)、許容できる回避策を考え出しました...

Luceneがインデックスから結果を返すとき、それぞれに次のような形式hitのフィールドがあります(同じアイテムの3つのバージョン、最後の番号はバージョンです)。"_id"

"CCB75380-4E9A-4921-99EC-65E532E330FF%en%1"
"CCB75380-4E9A-4921-99EC-65E532E330FF%en%2"
"CCB75380-4E9A-4921-99EC-65E532E330FF%en%3"
...

現在、どちらがデフォルトであるかで並べ替えてSort.RELEVANCEいます。インデックスにアイテムのバージョンが1つしかない場合はこれで問題ありませんが、ほぼ同じバージョンがいくつかある場合、それらはすべて同じ関連性スコアを持ち、Luceneはそれらを任意の順序で解き放ちます。次に、Sitecoreはアイテムバージョンの最初のインスタンスを取得します(古い場合でも)。

解決策は、2次ソートフィールドを指定することです。このメソッドでは、カスタムオブジェクトsearchContext.Search()を渡すことができます。Sort

searchContext.Search(query, new Sort(...));

Luceneの組み込みをSort.RELEVANCE最初に並べ替え、次にインデックスのidフィールド(降順)で並べ替えることで、hitSitecoreが最初に表示するのは、ランダムなバージョンではなく、最新バージョンになるようにすることができます。

searchContext.Search(query, new Sort
                            (
                                new SortField[2] 
                                {
                                    SortField.FIELD_SCORE, // equivalent to Sort.RELEVANCE
                                    new SortField("_id",SortField.STRING, true) // sort by _id, descending
                                }
                            )
);

パラメータは次のSortFieldとおりです。

SortField(string fieldName, int type, bool reverse)

このアプローチで私の問題は解決しましたが、最新バージョンのみをインデックスに登録する方法を誰かが実際に見つけることができる場合は、回答してください。

于 2012-12-05T15:03:18.297 に答える
0

私は上記の答えから別の解決策を考え出すことになりました、

アーキテクチャ的に言えば、この問題の理想的な解決策は、マスターデータベースインデックスから完全に削除するのではなく、より高いレベルでカスタムコードを使用して古いバージョンの結果を除外することだと思います。目前の問題を解決するためにsitecoreが機能するように設計されている方法を管理したくありません。

以下の述語を使用して、古いバージョンを除外し、最新バージョンのみを取得します

predicate.And(item=>item[Sitecore.ContentSearch.BuiltinFields.LatestVersion].Equals("1"));

これが誰かに役立つことを願っています!

于 2019-08-23T18:58:27.333 に答える