使用elasticsearch搜索用户
我尝试在elasticsearch中搜索用户。我有一个用户,“安迪”在索引中。当我搜索“gujjghjhgj”时,我从elasticsearch获得一位用户(Andy)。为什么?如果没有找到用户,则不返回任何内容。我怎样才能做到这一点?我有这个:使用elasticsearch搜索用户
var ui = new UserInfo { UserName = "Andy", Name = "", UserNr = 1};
Client.CreateIndex("users");
Client.Update<UserInfo, UserInfo>
(DocumentPath<UserInfo>
.Id(ui.UserNr), descriptor => descriptor.Doc(ui).DocAsUpsert().Refresh()
);
var Result = Client.Search<UserInfo>(s => s
.Index("users")
.Query(q => q.Match(m => m.Query(name)
))
.Size(pageSize)
.From((currentPage - 1)*pageSize));
unitItems = Result.Total;
return Result.Documents.ToList();
[Serializable, ElasticsearchType(IdProperty = "UserNr")]
public class UserInfo
{
public string UserName { get; set; }
public string Name { get; set; }
public string Avatar { get; set; }
public int UserNr { get; set; }
}
您的搜索的问题是,它没有指定一个字段来执行match
查询;与之匹配的值是指定的,但不是字段。
在这种情况下,NEST's conditionless query logic(注:这是旧的文档,但conditionless查询适用于NEST的新版本)踢和,因为现场没有一个值,该match
查询不发出的部分的搜索请求。请求最终看起来像
POST http://localhost:9200/users/userinfo/_search
{
"from":0,
"size":10
}
与文件与UserNr
1返回。
要解决这个问题,您只需指定字段名称即可。下面是一个完整的示例
void Main()
{
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var connectionSettings = new ConnectionSettings(pool)
// Disabling direct streaming and logging out requests and responses
// is useful during development, but may not want to do this
// in production as it has performance implications.
// Used here to write out requests and responses.
.DisableDirectStreaming()
.OnRequestCompleted(response =>
{
// log out the request
if (response.RequestBodyInBytes != null)
{
Console.WriteLine(
$"{response.HttpMethod} {response.Uri} \n" +
$"{Encoding.UTF8.GetString(response.RequestBodyInBytes)}");
}
else
{
Console.WriteLine($"{response.HttpMethod} {response.Uri}");
}
// log out the response
if (response.ResponseBodyInBytes != null)
{
Console.WriteLine($"Status: {response.HttpStatusCode}\n" +
$"{Encoding.UTF8.GetString(response.ResponseBodyInBytes)}\n" +
$"{new string('-', 30)}\n");
}
else
{
Console.WriteLine($"Status: {response.HttpStatusCode}\n" +
$"{new string('-', 30)}\n");
}
})
.DefaultIndex("users");
var client = new ElasticClient(connectionSettings);
var ui = new UserInfo { UserName = "Andy", Name = "", UserNr = 1 };
if (!client.IndexExists("users").Exists)
{
client.CreateIndex("users");
}
// can use index
client.Index(ui, descriptor => descriptor.Refresh());
var pageSize = 10;
var currentPage = 1;
var name = "gujjghjhgj";
var searchResponse = client.Search<UserInfo>(s => s
.Index("users")
.Query(q => q
.Match(m => m
// specify the field
.Field(f => f.UserName)
.Query(name)
)
)
.Size(pageSize)
.From((currentPage - 1) * pageSize)
);
var total = searchResponse.Total;
var docs = searchResponse.Documents.ToList();
}
[Serializable, ElasticsearchType(IdProperty = "UserNr")]
public class UserInfo
{
public string UserName { get; set; }
public string Name { get; set; }
public string Avatar { get; set; }
public int UserNr { get; set; }
}
Thanx。但是现在当我搜索“安迪”时,我得到了一位用户,但是当我搜索“An”或“And”时,我没有收到任何回应。为什么? :( – mrcode
这是最好的问题:)作为一个单独的问题:)简而言之,这是因为'UserName'属性映射默认使用标准分析器,所以没有对输入运行'ngram'(或'edge ngram')分析。另外,'match'查询不会执行前缀匹配。为了解决这个问题,你可以使用'前缀查询',或者如果你希望做大量的前缀匹配,就更新映射来将'UserName'映射为一个'multi_field'并使用不同类型的分析,并重新索引你的文档。 –
@mrcode请打开另一个问题,因为这个问题是一个新的,不同的问题。 –
“UserInfo”的映射是什么样的?它是明确定义还是推断? –