C# Elasticsearch NEST无法转换lambda表达式

4
我遇到了完全相同的问题,这个问题在这里描述(但没有得到回答)ElasticSearch NEST Search 我使用:
  1. .NET Framework 4.5;

  2. ASP.NET MVC 5;

  3. Elasticsearch 1.6.0 (运行在服务器上);

  4. Elasticsearch.NET 1.6.1

  5. NEST 1.6.1

我有一个MVC控制器,其中包含两个操作:
  1. Index - which contains HTML UI form

  2. Search - which contains Elasticsearch.NET client and a query.

    public ActionResult Search(SearchCreteria sc)
    {
      Settings settings = new Settings();
      Client client = new Client(settings);
      ElasticsearchClient esClient = client.Get();
    
      var test = esClient.Search<Contract>(body => body.Query(query => query.QueryString(qs => qs.Query("test"))));
    
      return View(test);
    }
    
在上述代码中,整个“body => body.Query(query => query.QueryString(qs => qs.Query("test")))”lambda表达式都有波浪线和以下工具提示:

(Parameter) ? body

Error:

Cannot convert lambda expression to type 'object' because it is not a delegate type

我通过谷歌搜索发现,在99%的情况下,人们忘记了包含一个程序集,通常是System.Linq

好吧.. 我肯定没有忘记添加那个,但我认为也许我必须包含一个NEST特定的程序集或类似的东西(除了NEST本身),所以我决定添加我认为可能与此相关的所有内容,最终得到了这个:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Web.Mvc;
using WebUI.Models.Concrete;

using Domain.Concrete.Entities;
using Domain.Concrete.Connectivity.Elastic;
using Domain.Concrete.Processors.Elastic;

using Elasticsearch;
using Elasticsearch.Net;
using Elasticsearch.Net.Connection.Configuration;
using Elasticsearch.Net.Connection.RequestState;
using Elasticsearch.Net.Connection.Security;
using Elasticsearch.Net.ConnectionPool;
using Elasticsearch.Net.Exceptions;
using Elasticsearch.Net.Providers;
using Elasticsearch.Net.Serialization;

using Nest;
using Nest.Domain;
using Nest.DSL.Descriptors;
using Nest.DSL.Query;
using Nest.DSL.Query.Behaviour;
using Nest.DSL.Visitor;
using Nest.Resolvers.Converters.Aggregations;
using Nest.Resolvers.Converters.Filters;
using Nest.Resolvers.Converters.Queries;
using Nest.Resolvers.Writers;

虽然效果不如预期,但还是值得一试。现在,我不确定问题出在哪里,非常感谢任何帮助。


我无法重现你的问题。尝试使用<dynamic>代替Contract,并通过.Type("yourType")指定搜索中的类型,或者使用.AllTypes()。后者可能不会特定于合同,但也许能够阐明实际的问题。 - Daniel Hoffmann-Mitscherling
很抱歉,如果无法重现您的问题,我就无法提供帮助。 - Daniel Hoffmann-Mitscherling
尝试使用ElasticClient而不是ElasticsearchClient。 - Rob
Rob。那个方法确实有效。谢谢你的提示。我不知道NEST有自己的客户端。在文档中,你只能找到ElasticsearchClient。 - Alex Purice
有人发布了一个对我有效的提示,然后又删除了该提示。我不会将该提示作为答案发布,因为它不是一个答案,而是一个有用的临时措施。所以这个提示是使用NEST的客户端而不是Elasticsearch.NET的客户端。我添加了一些代码来使用该客户端,并开始从ES中提取数据。总比没有好吧。 - Alex Purice
显示剩余3条评论
2个回答

5

在问题的评论中已经提供了答案,但为了方便未来的谷歌用户,我补充一下。

Elasticsearch.NET

它是一个基本的低级别ElasticsearchClient客户端,只接受字符串、匿名/动态对象或byte[]。同样地,它也没有返回响应的类型。当配置时,此客户端支持连接池和节点故障转移。80% 的此客户端是自动生成的。

仅当您正在与 Elasticsearch 进行集成并且仅存在少量调用时,并且不想引入例如Json.NET之类的依赖项时,才有用。只使用这个库的一个例子是Serilog.Sinks.Elasticsearch

NEST

高级别的ElasticClient客户端拥有 99.9% 所有请求和响应的类型。99/100 次这是您要使用的客户端。NEST 在幕后使用 Elasticsearch.NET 分派请求到正确的 Elasticsearch API 端点,并使用相同的连接池和故障转移基础结构。


它在本质上是正确的。然而,我想指出ElasticClient的信息极其有限。事实上,在Rob(Rob Jul 3 at 8:15)告诉我之前,我不知道它的存在。如果你搜索ElasticClient,Google只会弹出这个页面http://nest.azurewebsites.net/nest/quick-start.html,并且该信息仅在该页面的两段中提供。如果你错过了它,那就麻烦了。所以 - 是的,正确的答案总是使用ElasticClient,而不是ElasticserachClient。 - Alex Purice
感谢您的反馈,Alex。我们将更新我们的快速入门指南,明确提到这一点。 - Martijn Laarman

-1

我可以举一个如何使用NEST的例子。

var node = new Uri(elasticSearchURI);
var connectionPool = new SniffingConnectionPool(new[] { node });

var config = new ConnectionSettings(connectionPool)
                        .SniffOnConnectionFault(false)
                        .SniffOnStartup(false)
                        .SetTimeout(600000)
                        .DisablePing();

_Instance = new ElasticClient(config);

var result = _Instance.Search<Location>(s => s
              .Index("index")
              .Type("type")
              .Query(q =>
              {
                QueryContainer locationQuery = null;
                locationQuery |= q.QueryString(qs=>qs.OnFields(f => f.RecordValue).Query(term).MinimumShouldMatchPercentage(100));
                return locationQuery;
              })
             .Take(1)
             .Sort(sort => sort.OnField("_score").Descending())
           );

或者,如果您不想使用QueryContainers

   var result = _Instance.Search<Location>(s => s
                  .Index("index")
                  .Type("type")
                  .Query(q => q.QueryString(qs=>qs.OnFields(f => f.RecordValue).Query(term).MinimumShouldMatchPercentage(100))
                  .Take(10)
                  .Sort(sort => sort.OnField("_score").Descending())
               );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接