在查询某些字段时,使用NEST搜索不会返回结果

时间:2014-07-27 18:16:29

标签: c# .net elasticsearch nest

我正在使用Elastic Search开发.NET应用程序。我使用ES River来索引数据。 结果(在Sense中)看起来有点像这样:

 {
    "_index": "musicstore",
    "_type": "songs",
    "_id": "J2k-NjXjRa-mgWKAq0RMlw",
    "_score": 1,
    "_source": {
       "songID": 42,
       "tempo": "andante",
       "metrum": "3/4 E8",
       "intonation": "F",
       "title": "Song",
       "archiveSongNumber": "3684",
       "Year": 2000,
       "Place": "London"
    }
 },

要访问索引数据,我使用与此类似的NEST查询:

var result = ElasticClient.Search<Song>(s => s.Query(q => q.Term(p => p.title, "Song")));

当我搜索某个字段时,我遇到的问题是查询没有返回任何结果。 例如,当我搜索标题,songID,tempo或archiveSongNumber时,查询工作正常,它返回与Sense相同的结果,但是当我搜索Year,Place,metrum等时,查询不会返回任何结果,但是应该(Sense确实应该)。 像这样的查询工作(并返回正确的结果):

var result = ElasticClient.Search<Song>(s => s.Query(q => q.Term(p => p.title, "Song")));        
var result = ElasticClient.Search<Song>(s => s.Query(q => q.Term(p => p.songID, 42)));
var result = ElasticClient.Search<Song>(s => s.Query(q => q.Term(p => p.archiveSongNumber , "3684")));

这样的查询不会返回任何结果(但它们应该):

var result = ElasticClient.Search<Song>(s => s.Query(q => q.Term(p => p.Place, "London")));
var result = ElasticClient.Search<Song>(s => s.Query(q => q.Term(p => p.Year, 2000)));

我做错了什么?我在索引数据时是不是搞砸了?

更新 映射看起来像这样:

{
   "musicstore": {
      "mappings": {
         "songs": {
            "properties": {
               "Year": {
                  "type": "long"
               },
               "Place": {
                  "type": "string"
               },
               "archiveSongNumber": {
                  "type": "string"
               },
               "songID": {
                  "type": "long"
               },
               "intonation": {
                  "type": "string"
               },
               "metrum": {
                  "type": "string"
               },
               "title": {
                  "type": "string"
               },
               "tempo": {
                  "type": "string"
               }
            }
         }
      }
   }
}

更新2:

ES河流请求如下所示:

PUT /_river/songs_river/_meta
{
    "type":"jdbc",
    "jdbc": {
        "driver":"com.microsoft.sqlserver.jdbc.SQLServerDriver",
        "url":"jdbc:sqlserver://ip_address:1433;databaseName=database",
        "user":"user",
        "password":"password",
        "strategy":"simple",
        "poll":"300s",
        "autocommit":true,
        "fetchsize":10,
        "max_retries":3,
        "max_retries_wait":"10s",
        "index":"musicstore", 
        "type":"songs",
        "analysis": {
            "analyzer" :{ 
                "whitespace" :{ 
                    "type" : "whitespace",
                    "filter":"lowercase"
                }
            }
        },
        "sql":"some_sql_query"
    }
}

ES客户端配置如下所示:

private static ElasticClient ElasticClient
{
    get
    {
        Uri localhost = new Uri("http://localhost:9200");
        var setting = new ConnectionSettings(localhost);
        setting.SetDefaultIndex("musicstore").MapDefaultTypeNames(d => d.Add(typeof(Song), "songs"));
        setting.SetConnectionStatusHandler(c =>
        {
            if (!c.Success)
                throw new Exception(c.ToString());
        });
        return new ElasticClient(setting);
    }
}

2 个答案:

答案 0 :(得分:2)

通过查看您的映射,此处的问题很可能是您的所有字段在编制索引时都是analyzed,但您正在使用term queries与NEST,not analyzed,意思是他们只能找到完全匹配。如果您未在映射中明确指定分析器,则Elasticsearch默认为standard analyzer

当您使用查询字符串在Elasticsearch中执行搜索时,就像您在Sense中所做的那样:GET _search/?q=Place:Londonquery string query是由Elasticsearch运行的,这是不同于term query

从您的示例来看,您实际上看起来并没有使用query string syntax。您可能需要match query代替:

client.Search<Song>(s => s
    .Query(q => q
        .Match(m => m
            .OnField(p => p.Place)
            .Query("London")
        )
    )
);

如果您确实想要使用感知执行的query string query,那么您可以使用QueryString

client.Search<Song>(s => s
    .Query(q => q
        .QueryString(qs => qs
            .OnFields(p => p.Place)
            .Query("London")
        )
    )
);

希望有所帮助。我建议您查看getting started guide,特别是exact values vs. full text上的部分。

答案 1 :(得分:0)

在您的字词字段中添加“关键字”后缀:

var result = ElasticClient.Search<Song>(s => s
            .Query(q => q
            .Term(p => p
                        .Field(x => x.Year.Suffix("keyword")).Value(2000))));

尝试一下,它将起作用!