EasyNet.Solr具有以下特点:
EasyNet.Solr has the following characteristics:
- 基于接口的序列化,不采用反射,具有很高的性能 Serialization-based interface, do not use reflection, high performance
- 简单接口 Simple interface
- 基于Solr Binary Streaming协议 Agreement based on Solr Binary Streaming
索引和检索用到的实体类 Indexing and retrieval of entity class used
class IndexBook
{
public long BookId { get; set; }
public long UserId { get; set; }
public string UserName { get; set; }
public int AgeId { get; set; }
public string AgeName { get; set; }
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public string BookName { get; set; }
public string ContentDesc { get; set; }
public string BookTag { get; set; }
public int[] TagId { get; set; }
public string[] Tag { get; set; }
public int BookState { get; set; }
public int CheckUp { get; set; }
public int IsVip { get; set; }
public DateTime UpdateTime { get; set; }
public int WordCount { get; set; }
public int FavorCount { get; set; }
public int ShareCount { get; set; }
public int PointCount { get; set; }
public int ClickCount { get; set; }
}
创建索引 Create index
序列化实现 Implement serialization
class IndexBookSerializer : IObjectSerializer<IndexBook>
{
public IEnumerable<SolrInputDocument> Serialize(IEnumerable<IndexBook> objs)
{
if (objs == null)
{
yield return null;
}
foreach (var book in objs)
{
var doc = new SolrInputDocument();
doc.Add("bookid", new SolrInputField("bookid", book.BookId));
doc.Add("userid", new SolrInputField("userid", book.UserId));
doc.Add("username", new SolrInputField("username", book.UserName));
doc.Add("username_py", new SolrInputField("username_py", book.UserName.ToPinyin()));
doc.Add("ageid", new SolrInputField("ageid", book.AgeId));
doc.Add("agename", new SolrInputField("agename", book.AgeName));
doc.Add("agename_py", new SolrInputField("agename_py", book.AgeName.ToPinyin()));
doc.Add("categoryid", new SolrInputField("categoryid", book.CategoryId));
doc.Add("categoryname", new SolrInputField("categoryname", book.CategoryName));
doc.Add("categoryname_py", new SolrInputField("categoryname_py", book.CategoryName.ToPinyin()));
doc.Add("bookname", new SolrInputField("bookname", book.BookName));
doc.Add("bookname_py", new SolrInputField("bookname_py", book.BookName.ToPinyin()));
doc.Add("contentdesc", new SolrInputField("contentdesc", book.ContentDesc));
doc.Add("tagid", new SolrInputField("tagid", book.TagId));
doc.Add("tag", new SolrInputField("tag", book.Tag));
doc.Add("tag_mv_py", new SolrInputField("tag_mv_py", (from e in book.Tag select e.ToPinyin()).Distinct().ToArray()));
doc.Add("bookstate", new SolrInputField("bookstate", book.BookState));
doc.Add("checkUp", new SolrInputField("checkup", book.CheckUp));
doc.Add("isvip", new SolrInputField("isvip", book.IsVip));
doc.Add("updatetime", new SolrInputField("updatetime", book.UpdateTime));
doc.Add("wordcount", new SolrInputField("wordcount", book.WordCount));
doc.Add("favorcount", new SolrInputField("favorcount", book.FavorCount));
doc.Add("sharecount", new SolrInputField("sharecount", book.ShareCount));
doc.Add("pointcount", new SolrInputField("pointcount", book.PointCount));
doc.Add("clickcount", new SolrInputField("clickcount", book.ClickCount));
yield return doc;
}
}
}
索引 Index
class IndexBookDataConvert : IDbDataConvert<IndexBook>
{
public IEnumerable<IndexBook> Convert(IDataReader dataReader)
{
if (dataReader == null)
{
yield return null;
}
while (dataReader.Read())
{
var book = new IndexBook()
{
BookId = dataReader.GetInt64(0),
UserId = dataReader.GetInt64(1),
UserName = dataReader.GetString(2),
AgeId = dataReader.GetInt32(3),
AgeName = dataReader.GetString(4),
CategoryId = dataReader.GetInt32(5),
CategoryName = dataReader.GetString(6),
BookTag = dataReader.GetString(7),
BookState = dataReader.GetInt16(8),
BookName = dataReader.GetString(9),
ContentDesc = dataReader.GetString(10),
CheckUp = dataReader.GetInt16(11),
IsVip = dataReader.GetInt16(12),
UpdateTime = dataReader.GetDateTime(13),
WordCount = dataReader.GetInt32(14),
FavorCount = dataReader.GetInt32(15),
ShareCount = dataReader.GetInt32(16),
PointCount = dataReader.GetInt32(17),
ClickCount = dataReader.GetInt32(18)
};
yield return book;
}
}
}
class BookIndexProcess : IIndexProcess
{
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
private const string commandText = @"SELECT * FROM `Book`";
private CommitOptions commitOptions = new CommitOptions();
private OptimizeOptions optimizeOptions = new OptimizeOptions();
private ISolrResponseParser<NamedList, ResponseHeader> binaryResponseHeaderParser = new BinaryResponseHeaderParser();
private IDbDataConvert<IndexBook> dataConvert = new IndexBookDataConvert();
private IObjectSerializer<IndexBook> objectSerializer = new IndexBookSerializer();
private IUpdateParametersConvert<NamedList> updateParametersConvert = new BinaryUpdateParametersConvert();
private ISolrUpdateConnection<NamedList, NamedList> solrUpdateConnection = new SolrUpdateConnection<NamedList, NamedList>() { ServerUrl = ConfigurationManager.AppSettings["BookIndexSolrServerUrl"] };
private ISolrUpdateOperations<NamedList> updateOperations;
public BookIndexProcess()
{
updateOperations = new SolrUpdateOperations<NamedList, NamedList>(solrUpdateConnection, updateParametersConvert);
}
public void Process()
{
IList<IndexBook> books = null;
using (var reader = MySqlHelper.ExecuteReader(DbConnString.CoreReaderString, commandText))
{
books = dataConvert.Convert(reader).ToList();
}
if (books != null && books.Count > 0)
{
var result = updateOperations.Update(new UpdateOptions() { DelByQ = new string[] { "*:*" }, CommitOptions = commitOptions });
var header = binaryResponseHeaderParser.Parse(result);
logger.Info("Delete Status:{0} QTime:{1}", header.Status, header.QTime);
result = updateOperations.Update(new UpdateOptions() { OptimizeOptions = optimizeOptions, Docs = objectSerializer.Serialize(books) });
header = binaryResponseHeaderParser.Parse(result);
logger.Info("Count:{0} Status:{1} QTime:{2}", books.Count, header.Status, header.QTime);
}
}
}
查询 Query
反序列实现 Implement deserialize
public class SearchBookDeserializer : IObjectDeserializer<SearchBook>
{
public IEnumerable<SearchBook> Deserialize(SolrDocumentList result)
{
if (result == null)
{
yield return null;
}
foreach (var doc in result)
{
var book = new SearchBook()
{
BookId = Convert.ToInt64(doc["bookid"])
};
if (doc.ContainsKey("userid"))
{
book.UserId = Convert.ToInt64(doc["userid"]);
}
if (doc.ContainsKey("username"))
{
book.UserName = doc["username"].ToString();
}
if (doc.ContainsKey("ageid"))
{
book.AgeId = Convert.ToInt32(doc["ageid"]);
}
if (doc.ContainsKey("agename"))
{
book.AgeName = doc["agename"].ToString();
}
if (doc.ContainsKey("categoryid"))
{
book.CategoryId = Convert.ToInt32(doc["categoryid"]);
}
if (doc.ContainsKey("categoryname"))
{
book.CategoryName = doc["categoryname"].ToString();
}
if (doc.ContainsKey("bookname"))
{
book.BookName = doc["bookname"].ToString();
}
if (doc.ContainsKey("contentdesc"))
{
book.ContentDesc = doc["contentdesc"].ToString();
}
if (doc.ContainsKey("tag"))
{
var array = (ArrayList)doc["tag"];
if (array != null)
{
book.Tag = new string[array.Count];
for (var i = 0; i < array.Count; i++)
{
book.Tag[i] = array[i].ToString();
}
}
}
if (doc.ContainsKey("bookstate"))
{
book.BookState = (BookStateEnum)doc["bookstate"];
}
if (doc.ContainsKey("isvip"))
{
book.IsVip = Convert.ToInt32(doc["isvip"]);
}
yield return book;
}
}
}
查询 Query
private static readonly ISolrQueryOperations<NamedList> queryOperations = new SolrQueryOperations<NamedList>(new SolrReadonlyConnection<NamedList>() { ServerUrl = ConfigurationManager.AppSettings["BookSearchSolrServerUrl"] });
private static readonly ISolrResponseParser<NamedList, QueryResults<SearchBook>> binaryQueryResultsParser = new BinaryQueryResultsParser<SearchBook>(new SearchBookDeserializer());
private static readonly ISolrResponseParser<NamedList, IDictionary<string, IDictionary<string, IList<string>>>> binaryHighlightingParser = new BinaryHighlightingParser();
IDictionary<string, ICollection<string>> options = new Dictionary<string, ICollection<string>>();
options[CommonParams.SORT] = new string[] { "score desc,clickcount desc" };
options[CommonParams.START] = new string[] { "0" };
options[CommonParams.ROWS] = new string[] { "20" };
var namedList = queryOperations.Query(SolrQuery.All, options);
var queryResult = binaryQueryResultsParser.Parse(namedList);
var hightlightResult = binaryHighlightingParser.Parse(namedList);