带有空格的Elasticsearch Nest通配符查询

我想使用Nest编写一个elasticsearch查询,以获取ContentIndexables已被索引的完整索引项(在我的情况下为自定义类型)。该查询受[somestring] + *(即String.StartsWith())的术语查询的约束,其中[somestring]可能包含空格,也可能不包含空格。

这与CompletionSuggester由于我需要检索完整对象而不是字符串建议而不同。

当我查询没有空格的文本时,将使用下面的代码返回所需的输出。但是,如果我的搜索词包含空格,则不会返回预期结果。

这是我搜索字段的方式:

var searchResults = _client.Search<ContentIndexable>(

body =>

body

.Index(indexName)

.Query(

query =>

query.QueryString(

qs => qs.

OnFields(f => f.Title, f => f.TextContent)

.Query(searchTerm + "*"))));

这是一个单元测试,演示了如何重现该问题:

indexService.IndexUserItemsSync(testGuid, IndexType.submission, new ContentIndexable

{

ContentId = Guid.NewGuid(),

TextContent = "Some description",

Title = "title"

});

indexService.IndexUserItemsSync(testGuid, IndexType.submission, new ContentIndexable

{

ContentId = Guid.NewGuid(),

TextContent = "Some description",

Title = "title that is long"

});

indexService.IndexUserItemsSync(testGuid, IndexType.submission, new ContentIndexable

{

ContentId = Guid.NewGuid(),

TextContent = "Some description",

Title = "title that likes"

});

indexService.IndexUserItemsSync(testGuid, IndexType.submission, new ContentIndexable

{

ContentId = Guid.NewGuid(),

TextContent = "Some description",

Title = "titlethat"

});

var searchResult = indexService.SearchUserItems(testGuid, IndexType.submission, 10, "title");

Assert.IsNotNull(searchResult);

// this one works

Assert.AreEqual(4, searchResult.Count());

var searchResult2 = indexService.SearchUserItems(testGuid, IndexType.submission, 10, "title that");

Assert.IsNotNull(searchResult2);

// this one does not!!! searchREsult2.Count() evaluates to 0

Assert.AreEqual(2, searchResult2.Count());

如您所见,然后输入“ title that”,搜索返回为空,而不是我希望返回的两行。

更多信息:我在我的ContentIndexable类型上创建了一个索引:

public class ContentIndexable : IIndexable

{

public Guid ContentId { get; set; }

public string Title { get; set; }

public string TextContent { get; set; }

}

使用此代码:

_client.CreateIndex(

indexName,

descriptor =>

descriptor.AddMapping<ContentIndexable>(

m => m.Properties(

p => p.Completion(s => s

.Name(n => n.Title)

.IndexAnalyzer("standard")

.SearchAnalyzer("standard")

.MaxInputLength(30)

.Payloads()

.PreserveSeparators()

.PreservePositionIncrements())

.Completion(s => s.Name(n => n.TextContent)

.IndexAnalyzer("standard")

.SearchAnalyzer("standard")

.MaxInputLength(50)

.Payloads()

.PreserveSeparators()

.PreservePositionIncrements())

)));

我什至在索引或查询时都试图转义空白,string.Replace(" ", @"\ ")但这没有帮助。

将搜索类型更改为通配符也无济于事:

var searchResults = _client.Search<ContentIndexable>(

body =>

body

.Index(indexName)

.Query(

query => query.Wildcard(qd => qd.OnField(f => f.Title).Value(searchTerm + "*"))));

有人知道我在做什么错吗?

请注意,我的CompletionSuggester版本可以使用空格,但不幸的是只能返回字符串。我需要拿出

才能拿到ContentId。MY CompletionSuggester实施:

public IEnumerable<string> GetAutoCompleteSuggestions(Guid userId, IndexType indexType, int size, string searchTerm)

{

string indexName = getIndexName(indexType, userId);

var result = _client.Search<ContentIndexable>(

body => body.Index(indexName)

.SuggestCompletion("content-suggest" + Guid.NewGuid(),

descriptor => descriptor

.OnField(t => t.Title)

.Text(searchTerm)

.Size(size)));

if (result.Suggest == null)

{

return new List<string>();

}

return (from suggest in result.Suggest

from value in suggest.Value

from options in value.Options

select options.Text).Take(size);

}

我知道我可以接受建议,获得全部价值(这将导致我期望的两个项目),然后使用我的第一种方法进行全期匹配,但这需要对ElasticSearch进行2次单独的调用(一个用于完整的建议者和第二个用于术语查询),但理想情况下,如果可能的话,我希望不进行往返。

提前谢谢了,

回答:

这是您如何解决Title现场问题的示例。

将您的映射更改为类似(或使用MultiField,但我找不到同时将字段映射为字符串和完成的选项):

client.CreateIndex(indexName, i => i

.AddMapping<ContentIndexable>(m => m

.Properties(

ps => ps

.Completion(c => c.Name("title.completion")

.IndexAnalyzer("standard")

.SearchAnalyzer("standard")

.MaxInputLength(30)

.Payloads()

.PreserveSeparators()

.PreservePositionIncrements())

.String(s => s.Name(x => x.Title).CopyTo("title.completion")))));

更改SuggestCompletion

var result = client.Search<ContentIndexable>(body => body

.Index(indexName)

.SuggestCompletion("content-suggest" + Guid.NewGuid(),

descriptor => descriptor

.OnField(t => t.Title.Suffix("completion"))

.Text("title")

.Size(10)));

QueryString

var searchResponse = client.Search<ContentIndexable>(body => body

.Index(indexName)

.Query(query => query

.QueryString(

qs => qs

.OnFields(f => f.Title.Suffix("completion"))

.Query("title tha" + "*")

.MinimumShouldMatchPercentage(100))));

该解决方案的问题是事实,我们为Title字段存储了两次数据。这就是为什么我前面提到使用MultiField很好,但是我无法使用NEST

希望这可以帮助。

以上是 带有空格的Elasticsearch Nest通配符查询 的全部内容, 来源链接: utcz.com/qa/428501.html

回到顶部