2013-02-13 71 views
5

使用LINQ处理ElasticSearch结果的最有效方法是什么?使用LINQ处理弹性搜索结果

我遇到了JSON.Net的JObject Class

从ElasticSearch返回的JSON是否以适合通过JObject类的适当LINQ查询的方式构造?

+7

@BrandonMoretz [这是确定的提出和回答自己的问题](http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/)。在SO中获得好的答案有什么危害? – MikeSmithDev 2013-02-13 04:56:57

+2

尽管我自己回答了这个问题以分享我的解决方案,但我很乐意看到其他人。 – 2013-02-13 05:35:38

回答

6

这是一个关于如何利用LINQ处理来自elasticsearch引擎的JSON查询结果的完整解决方案。


连接库 - PlainElastic.NET

首先,我使用PlainElastic.NET单一用途:用于连接到我的服务器elasticsearch。这个库非常精简,包含简洁的GET,POST和PUT函数。这在下面用client连接对象发挥作用。 result.ToString()提供了来自elasticsearch服务器的JSON响应。只需将DLL放入你的bin并添加一个引用即可。

JSON处理器 - JSON.NET

我使用NewtonSoft JSON.NET的一个很大的特点,以方便LINQ查询。该库有一个JObject类,它提供了一个可嵌套的,可查询的结构来执行LINQ。请参阅下面的代码段,我抓住HitCount来了解获取单个值的好处,当然,请查看LINQ查询以了解如何查询它。记住,这只是一个数据结构,它是解析JSON字符串的结果。只需将DLL放入你的bin并添加一个引用即可。

执行查询对弹性搜索

'Execute the Search 
Dim client = New ElasticConnection("localhost", 9200) 
Dim result = client.Post("myindex/mytype/_search", elastic_query) 'elastic_query = well-formatted elasticsearch query (json string)' 
Dim J As JObject = JObject.Parse(result.ToString()) 

'How many results were located? 
Dim HitCount = CInt(J("hits")("total")) 

'What was the maximum score? Maybe you want to know this for normalizing scores to 0-100. 
' - We make sure we have hits first 
' - Also, make sure scoring is turned on. It might be turned off if an alternate sort method is used in your query 
If HitCount > 0 AndAlso J("hits")("max_score").Type <> JTokenType.Null Then MaxScore = CDbl(J("hits")("max_score")) 

处理结果与LINQ

现在,使用LINQ结合GridView的,DataLists,中继器提供了一个美丽的匿名对象,等我故意提供了一个非平凡的LINQ查询的例子。这个例子被嵌套的数据(StoresCategories)现在

Dim SearchResults = _ 
    (From X In J("hits")("hits") 
    Select 
     score = CDec(If(X("_score").Type = JTokenType.Null, 0, X("_score"))), 
     boost = CDbl(X("_source")("_boost")), 
     InstitutionID = CInt(X("_source")("InstitutionID")), 
     Name = CStr(X("_source")("Name")), 
     Stores = (From S In X("_source")("Stores") Select CInt(S("StoreID"))).ToList(), 
     Categories = (From Z In X("_source")("Categories") Select CatID = CInt(Z("CatID")), CatName = CStr(Z("CatName")), InstitutionID = CInt(X("_source")("InstitutionID"))).ToList() 
Order By score Descending, boost Descending 
) 

,可以绑定到一个Repeater,DataList控件或GridView的

MyRepeater.DataSource = SearchResults 
MyRepeater.DataBind() 
+0

尽管如此,它依赖于用户生成的查询。如果你使用linq来过滤结果,那么所有这些都会发生在客户端,而这种错误会忽略弹性搜索的全部观点。我相信OP希望从链接表达式中实际生成es查询。有nuget包解决这个问题(例如ElasticLinq) – Basic 2015-07-06 00:30:50