我搜索了一个字段值,但它没有以突出显示的方式返回,同时我希望Solr不显示所有文档内容,只需几行。
solrconfig:
<!-- Highlighting defaults -->
<str name="hl">true</str>
<str name="hl.fl">*</str>
<str name="hl.requireFieldMatch">true</str>
<str name="hl.preserveMulti">true</str>
<str name="hl.encoder">html</str>
<str name="hl.useFastVectorHighlighter">true</str>
<str name="hl.maxAnalyzedChars">-1</str>
<str name="hl.simple.pre"><b style="background:yellow"></str>
<str name="hl.simple.post"></b></str>
<str name="hl.fragmentsBuilder">colored</str>
<str name="hl.fragsize">500</str> <!-- for all fields with standard highlighting -->
<str name="f.content_en.hl.snippets">3</str>
<str name="f.content_en.hl.fragsize">500</str>
<str name="f.content_en.hl.alternateField">content_en</str>
<str name="f.content_en.hl.maxAlternateFieldLength">500</str>
<str name="f.content_ar.hl.snippets">3</str>
<str name="f.content_ar.hl.fragsize">500</str>
<str name="f.content_ar.hl.alternateField">content_ar</str>
<str name="f.content_ar.hl.maxAlternateFieldLength">500</str>
<str name="f.content_undf.hl.snippets">3</str>
<str name="f.content_undf.hl.fragsize">500</str>
<str name="f.content_undf.hl.alternateField">content_undf</str>
<str name="f.content_undf.hl.maxAlternateFieldLength">500</str>
管理型模式:
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
<field name="title" type="text_general" indexed="true" stored="true" multiValued="false"/>
<field name="subject" type="text_general" indexed="true" stored="true"/>
<field name="description" type="text_general" indexed="true" stored="true"/>
<field name="comments" type="text_general" indexed="true" stored="true"/>
<field name="author" type="text_general" indexed="true" stored="false"/>
<field name="keywords" type="text_general" indexed="true" stored="true"/>
<field name="category" type="text_general" indexed="true" stored="true" multiValued="true"/>
<field name="last_modified" type="date" indexed="true" stored="true"/>
<field name="stream_name" type="string" indexed="true" stored="true"/>
<field name="stream_size" type="tlong" indexed="true" stored="true"/>
<field name="created" type="string" indexed="true" stored="true"/>
<field name="extension" type="string" indexed="true" stored="true"/>
<field name="resourcename" type="text_general" indexed="true" stored="true"/>
<field name="xmptpg_npages" type="tlong" indexed="true" stored="true"/>
<field name="content_type" type="string" indexed="true" stored="true" multiValued="false"/>
<field name="suggest" omitNorms="true" type="text_suggest" indexed="true" stored="false" multiValued="true"/>
<field name="shingle" omitNorms="true" type="text_shingle" indexed="true" stored="false" multiValued="true"/>
<field name="content_en" type="text_en" indexed="true" stored="true" multiValued="true"/>
<field name="content_ar" type="text_en" indexed="true" stored="true" multiValued="true"/>
<!-- Main body of document extracted by SolrCell.
NOTE: This field is not indexed by default, since it is also copied to "text"
using copyField below. This is to save space. Use this field for returning and
highlighting document content. Use the "text" field to search the content. -->
<field name="content" type="text_en" indexed="false" stored="true" multiValued="true"/>
<!-- catchall field, containing all other searchable text fields (implemented
via copyField further on in this schema -->
<field name="text" type="text_en" indexed="true" stored="false" multiValued="true"/>
<defaultSearchField>text</defaultSearchField>
<!-- DEPRECATED: The defaultOperator (AND|OR) is consulted by various query parsers
when parsing a query string to determine if a clause of the query should be marked as
required or optional, assuming the clause isn't already marked by some operator.
The default is OR, which is generally assumed so it is not a good idea to change it
globally here. The "q.op" request parameter takes precedence over this.
-->
<solrQueryParser defaultOperator="AND"/>
<!-- copyField commands copy one field to another at the time a document
is added to the index. It's used either to index the same field differently,
or to add multiple fields to the same field for easier/faster searching.
Text fields from SolrCell to search by default in our catch-all field -->
<copyField source="title" dest="text"/>
<copyField source="subject" dest="text"/>
<copyField source="comments" dest="text"/>
<copyField source="category" dest="text"/>
<copyField source="last_modified" dest="text"/>
<copyField source="author" dest="text"/>
<copyField source="description" dest="text"/>
<copyField source="keywords" dest="text"/>
<copyField source="content" dest="text"/>
<copyField source="resourcename" dest="text"/>
<copyField source="stream_name" dest="text"/>
<copyField source="extension" dest="text"/>
<copyField source="id" dest="text"/>
<copyField source="*_en" dest ="text" />
<copyField source="*_ar" dest ="text" />
<!-- suggest field for spell check dictionary -->
<copyField source="title" dest="suggest"/>
<copyField source="subject" dest="suggest"/>
<copyField source="comments" dest="suggest"/>
<copyField source="category" dest="suggest"/>
<copyField source="last_modified" dest="suggest"/>
<copyField source="author" dest="suggest"/>
<copyField source="description" dest="suggest"/>
<copyField source="keywords" dest="suggest"/>
<copyField source="content" dest="suggest"/>
<copyField source="stream_name" dest="suggest"/>
<copyField source="extension" dest="suggest"/>
<copyField source="*_undf" dest ="suggest" />
<copyField source="*_en" dest ="suggest" />
<copyField source="*_ar" dest ="suggest" />
<!-- Shingle field for autocomplete Search-->
<copyField source="title" dest="shingle"/>
<copyField source="subject" dest="shingle"/>
<copyField source="comments" dest="shingle"/>
<copyField source="category" dest="shingle"/>
<copyField source="last_modified" dest="shingle"/>
<copyField source="author" dest="shingle"/>
<copyField source="description" dest="shingle"/>
<copyField source="keywords" dest="shingle"/>
<copyField source="content" dest="shingle"/>
<copyField source="stream_name" dest="shingle"/>
<copyField source="extension" dest="shingle"/>
<copyField source="*_undf" dest ="shingle" />
<copyField source="*_en" dest ="shingle" />
<copyField source="*_ar" dest ="shingle" />
<!-- Create a string version of some fields for faceting -->
<copyField source="extension" dest="extension_s"/>
<copyField source="category" dest="category_s"/>
型号:
using System;
using System.Collections.Generic;
using SolrNet.Attributes;
namespace SampleSolrApp.Models
{
public class Product
{
[SolrUniqueKey("id")]
public string Id { get; set; }
[SolrField("sku")]
public string SKU { get; set; }
[SolrField("name")]
public string Name { get; set; }
[SolrField("manu_exact")]
public string Manufacturer { get; set; }
[SolrField("cat")]
public ICollection<string> Categories { get; set; }
[SolrField("features")]
public ICollection<string> Features { get; set; }
[SolrField("price")]
public decimal Price { get; set; }
[SolrField("popularity")]
public int Popularity { get; set; }
[SolrField("inStock")]
public bool InStock { get; set; }
[SolrField("timestamp")]
public DateTime Timestamp { get; set; }
[SolrField("weight")]
public double? Weight { get; set; }
[SolrField("title")]
public string title { get; set; }
[SolrField("subject")]
public string subject { get; set; }
[SolrField("description")]
public string description { get; set; }
[SolrField("comments")]
public string comments { get; set; }
[SolrField("keywords")]
public string keywords { get; set; }
[SolrField("category")]
public ICollection<string> category { get; set; }
[SolrField("author")]
public string author { get; set; }
[SolrField("stream_name")]
public string stream_name { get; set; }
[SolrField("stream_size")]
public string stream_size { get; set; }
[SolrField("created")]
public string created { get; set; }
[SolrField("extension")]
public string extension { get; set; }
[SolrField("resourcename")]
public string resourcename { get; set; }
[SolrField("text")]
public ICollection<string> text { get; set; }
[SolrField("content_en")]
public ICollection<string> content { get; set; }
[SolrField("content_ar")]
public ICollection<string> contentar { get; set; }
[SolrField("suggest")]
public ICollection<string> suggest { get; set; }
[SolrField("shingle")]
public ICollection<string> shingle { get; set; }
[SolrField("xmptpg_npages")]
public string xmptpg_npages { get; set; }
[SolrField("last_modified")]
public DateTime last_modified { get; set; }
[SolrField("content_type")]
public string content_type { get; set; }
}
}
控制器:
public ActionResult Index(SearchParameters parameters)
{
try
{
var start = (parameters.PageIndex - 1) * parameters.PageSize;
var matchingProducts = solr.Query(BuildQuery(parameters), new QueryOptions
{
Highlight= new HighlightingParameters
{
Fragsize = 250,
Fields = new[] { "text" },
BeforeTerm = "<b>",
AfterTerm = "</b>",
Snippets = 10,
MaxAnalyzedChars = 100000,
},
FilterQueries = BuildFilterQueries(parameters),
//Rows = parameters.PageSize,
Rows = 10,
Start = 0,
//Start = 10,
OrderBy = GetSelectedSort(parameters),
SpellCheck = new SpellCheckingParameters(),
Facet = new FacetParameters
{
Queries = AllFacetFields.Except(SelectedFacetFields(parameters))
.Select(f => new SolrFacetFieldQuery(f) { MinCount = 1 })
.Cast<ISolrFacetQuery>()
.ToList(),
},
});
var view = new ProductView
{
Products = matchingProducts,
Search = parameters,
TotalCount = matchingProducts.NumFound,
Facets = matchingProducts.FacetFields,
DidYouMean = GetSpellCheckingResult(matchingProducts),
};
return View(view);
}
catch (InvalidFieldException)
{
return View(new ProductView
{
QueryError = true,
});
}
}
查看:
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ProductView>" %>
<%@ Import Namespace="SampleSolrApp.Helpers"%>
<%@ Import Namespace="SampleSolrApp.Models"%>
<asp:Content ID="indexHead" ContentPlaceHolderID="head" runat="server">
<title>Hello World</title>
</asp:Content>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<form method="get" action="<%= Url.Action("Index") %>">
<%= Html.TextBox("q", Model.Search.FreeSearch) %>
<input type="submit" value="Search" />
<% if (!string.IsNullOrEmpty(Model.DidYouMean)) { %>
Did you mean <strong><em><a href="<%= Url.ForQuery(Model.DidYouMean) %>"><%= Model.DidYouMean%></a></em></strong>
<% } %>
<% if (Model.QueryError) { %>
<span class="error">Invalid query</span>
<% } %>
</form>
<%using (Html.BeginForm("IndexAndUpload", "Home", FormMethod.Post,
new { enctype = "multipart/form-data" } ))
{
Html.AntiForgeryToken();
%>
<fieldset style="display: block; margin: auto;">
<legend>Upload a file</legend>
<div class="editor-field">
<input type="file" value="Browse" name="file" />
</div>
<div class="editor-field">
<input type="submit" value="Index and Upload" style="display: block; margin: auto;"/>
</div>
</fieldset>
<% } %>
<!-- <div class="leftColumn">
<% foreach (var f in Model.Search.Facets) { %>
<ul>
<li>
<%= Html.SolrFieldPropName<Product>(f.Key) %>
<ul>
<li><a class="removeFacet" href="<%= Url.RemoveFacet(f.Key) %>"><%= f.Value %></a></li>
</ul>
</li>
</ul>
<% } %>
<ul>
<% foreach (var f in Model.Facets) { %>
<li>
<%= Html.SolrFieldPropName<Product>(f.Key) %>
<ul>
<% foreach (var fv in f.Value) { %>
<li><a href="<%= Url.SetFacet(f.Key, fv.Key) %>"><%= fv.Key %></a> <span>(<%= fv.Value %>)</span></li>
<%} %>
</ul>
</li>
<% } %>
</ul>
</div>
-->
<div class="rightColumn">
<div>
Sort by:
<% if (string.IsNullOrEmpty(Model.Search.Sort)) { %>
<strong>Best match</strong>
<% } else { %>
<a href="<%= Url.RemoveParameters("sort") %>">Best match</a>
<% } %>
|
<% if (Model.Search.Sort == "alphaNameSort") { %>
<strong>Name</strong>
<% } else { %>
<a href="<%= Url.SetParameter("sort", "alphaNameSort") %>">Name</a>
<% } %>
|
<% if (Model.Search.Sort == "price") { %>
<strong>Price</strong>
<% } else { %>
<a href="<%= Url.SetParameter("sort", "price") %>">Price</a>
<% } %>
|
<% if (Model.Search.Sort.NotNullAnd(s => s.StartsWith("random"))) { %>
<strong>Random</strong>
<% } else { %>
<a href="<%= Url.SetParameter("sort", "random_" + Html.RandomNumber()) %>">Random</a>
<% } %>
</div>
<div>
<% foreach (var p in Model.Products) { %>
<div class="product">
<div class="productName"><%= p.Name %></div>
Price: <span class="price"><%= p.Price.ToString("C") %></span><br />
Categories: <% Html.Repeat(p.Categories, cat => { %>
<a href="<%= Url.SetFacet("cat", cat) %>"><%= cat %></a><% }, () => {%>, <% }); %><br>
Content_Type: <span class="content-type"><%= p.content_type %></span><br />
Title: <span class="title"><%= p.title %></span><br />
Content-ar: <% Html.Repeat(p.contentar, ar => { %>
<a href="<%= Url.SetFacet("content_ar", ar) %>"><%= ar %></a><% }, () => {%>, <% }); %><br> -->
<%StringBuilder builder = new StringBuilder();
if(p.content != null)
{
foreach(var c in p.content) {%>
<%builder.Append(c); %>
<%} }%>
Content-en: <span class="content"><%= builder%></span><br />
Content-ar: <span class="contentar"><%= p.contentar%></span><br />
</div>
<%}
%>
</div>
<% Html.RenderPartial("Pagination", new PaginationInfo {
PageUrl = Url.SetParameter("page", "!0"),
CurrentPage = Model.Search.PageIndex,
PageSize = Model.Search.PageSize,
TotalItemCount = Model.TotalCount,
}); %>
<div class="pagesize">
<% Html.Repeat(new[] { 5, 10, 20 }, ps => { %>
<% if (ps == Model.Search.PageSize) { %>
<span><%= ps%></span>
<% } else { %>
<a href="<%= Url.SetParameters(new {pagesize = ps, page = 1}) %>"><%= ps%></a>
<% } %>
<% }, () => { %> | <% }); %>
items per page
</div>
</div>
</asp:Content>
Solr Admin的Solr结果
{
"responseHeader":{
"status":0,
"QTime":16,
"params":{
"q":"Arduino",
"indent":"on",
"wt":"json",
"_":"1477734135388"}},
"response":{"numFound":1,"start":0,"maxScore":0.79364794,"docs":[
{
"id":"a.pdf",
"text":["a.pdf",
"",
"",
"2014-10-09T19:45:46Z",
"Arduino Programming Language",
"C:\\Users\...,
"Allison Okamura",
Arduino Programming Language \n \n \n Introduction to Haptics\n \n Arduino Programming Language\n \n Allison M. Okamura\nStanford University\n \n (optional material for beginning programmers) \n \n \n \n Programming Guidance\n \n Stanford University Introduction to Haptics ,
"keywords":"",
"subject":"",
"last_modified":"2014-10-09T19:45:46Z",
"title":"Arduino Programming Language",
"content_type":"application/pdf",
"stream_size":148285,
"created":"Thu Oct 09 19:45:46 UTC 2014",
"xmptpg_npages":23,
"resourcename":"C:\\Users...,
"language_s":"en",
"content_en":[\n Arduino Programming Language \n \n \n Introduction to Haptics\n \n Arduino Programming Language\n \n Allison M. Okamura\nStanford University,
"spellcheck":{
"suggestions":[],
"collations":[]}}
新结果
{
"responseHeader":{
"status":0,
"QTime":24,
"params":{
"q":"arduino",
"indent":"on",
"wt":"json",
"_":"1477737631856"}},
"response":{"numFound":1,"start":0,"maxScore":0.79364794,"docs":[
{
"id":"a.pdf",
"text":["a.pdf",
"",
"",
"2014-10-09T19:45:46Z",
"Arduino Programming Language",
"C:\\Users\\firas\\Desktop\\SampleSolrApp - true\\Content\\files\\a.pdf",
"Allison Okamura",
Introduction to Haptics\n \n Arduino Programming Language\n \n Allison M. Okamura\nStanford University\n \n (optional material for beginning programmers) ,
"keywords":"",
"subject":"",
"last_modified":"2014-10-09T19:45:46Z",
"title":"Arduino Programming Language",
"content_type":"application/pdf",
"stream_size":148285,
"created":"Thu Oct 09 19:45:46 UTC 2014",
"xmptpg_npages":23,
"resourcename":"C:\\Users\\firas\\Desktop\\SampleSolrApp - true\\Content\\files\\a.pdf",
"language_s":"en",
"content_en":Arduino Programming Language \n \n \n Introduction to Haptics\n \n Arduino Programming Language\n \n Allison M. Okamura\nStanford University\n \n (optional material for beginning programmers) ,
"highlighting":{
"a.pdf":{
"text":["a.pdf 2014-10-09T19:45:46Z <b style=\"background:yellow\">Arduino</b> Programming Language C:\\Users\\firas\\Desktop\\SampleSolrApp - true\\Content\\files\\a.pdf Allison Okamura style=\"background:yellow\">Arduino</b> Programming Language\n \n Allison M. Okamura\nStanford University\n \n (optional material for beginning programmers) \n \n \n \n Programming Guidance\n \n Stanford University "],
"title":["<b style=\"background:yellow\">Arduino</b> Programming Language"],
"language_s":["en"],
"content_en":<b style=\"background:yellow\">Arduino</b> Programming Language \n \n \n Introduction to Haptics\n \n <b style=\"background:yellow\">Arduino</b> Programming Language\n \n Allison M. Okamura\nStanford University\n \n (optional material for beginning programmers) \n \n \n \n Programming Guidance\n \n Stanford University Introduction to Haptics ",
"appropriate)\n• <b style=\"background:yellow\">Arduino</b>-specific tutorials\n \n In this class:\n• You will start from existing programs (sketches) and modify them\n• The complexity of the programming you will do is low\n• Debugging can be difficult because of the real-time nature of haptic \n \n interaction\n• You should learn by doing. There is little you can do to damage your \n \n Hapkit through programming mistakes! \n \n \n \n We will start by going through some examples at\n \n http://www.learn-c.org/ \n \n \n \n <b style=\"background:yellow\">Arduino</b> Programming Language",
" © Allison M. Okamura, 2014\n \n <b style=\"background:yellow\">Arduino</b> reference materials obtained from http://arduino.cc under a Commons Attribution-ShareAlike 3.0 License. \n \n Structure Variables Functions\n \n Basic syntax\n \n Arithmetic operators\n \n Control structures\n \n Comparison Operators\n \n Boolean Operators\n \n Constants\n \n Data types\n \n Scope\n \n Digital I/O\n \n Analog I/O\n \n Math\n \n Serial communication\n \n Defining your own \n \n \n \n <b style=\"background:yellow\">Arduino</b> Programming Language Components\n \n Stanford University "]}},
"spellcheck":{
"suggestions":[],
"collations":[]}}