我通过编写以下内容在Sitecore中实现了一个简单的搜索功能:
string searchStr = Server.UrlDecode(WebUtil.GetQueryString("searchStr"));
FullTextQuery query = new FullTextQuery(searchStr);
SearchHits hits = indexSearchContext.Search(query, int.MaxValue);
SearchResultCollection results = hits.FetchResults(0, 100);
这正确地获取了searchStr的所有出现。然后我循环结果并显示它们:
foreach (var result in results)
{
Item hit = result.GetObject<Item>();
if (hit != null)
{
string hitText = GenerateHitText(hit);
LiteralControl hitControl = new LiteralControl(hitText);
pnResultsPanel.Controls.Add(hitControl);
}
}
问题是我在页面上有文本框组件,搜索时也会返回这些组件。我不希望用户在搜索时看到组件,我只希望他们看到使用该组件的页面。我认为它看起来有点像这样:
foreach (var result in results)
{
Item hit = result.GetObject<Item>();
if (hit != null)
{
if (//hit is a component)
{
foreach (//page where hit (the component) is placed)
{
//Do something
}
}
}
}
任何人都可以帮我写一些可以实现这一目标的东西吗? 感谢。
答案 0 :(得分:0)
如果您仅将组件项目用作组件(即它们不能自行浏览),我认为应该相当简单:
foreach (var result in results)
{
Item hit = result.GetObject<Item>();
if (hit != null)
{
// Potentially you need to just check the __Renderings or
// __FinalRenderings field here instead
if (hit.Visualization.Layout == null)
{
foreach (Sitecore.Globals.LinkDatabase.GetReferrers(item))
{
//Do something
}
}
}
}
如果您将组件项目也用作常规页面,则可能会更复杂一些。
答案 1 :(得分:0)
如果您想要实施完整内容搜索,Lucene可能不是您的最佳选择。虽然如果你开始实现它,你可能会问,你可能会发现一些问题。
最好的方法是在索引中包含内容(请参阅Mareks评论)。但在开始之前分析您的解决方案,因为更新内容时可能会出现问题。
问题在于,有时候并非所有组件都与页面直接相关(通过数据源) - 否则您可以使用链接数据库,ComputedFields ......但不幸的是,并非总是如此。例如,当你有一个获取数据源的渲染时,它实际上是你正在显示的项目的父级...同时考虑到这可能不是现在的问题,但它也可能限制你在未来的开发中。
对于内容更新:如果您的组件内容发生变化,您的搜索需要知道。如果您的内容嵌入在索引中(这是最快的方式),这可能是一个问题。您需要一个解决方案来更新正确的项目,如果它们没有真正的链接,那就不那么容易了。
当然还有其他一些选择 - 例如每天重建一次索引。
所以这一切都取决于你的解决方案:结构,数据量......(并且不要只考虑现在&#39;但也要考虑未来)。