elasticsearch 嵌套:由于空搜索而导致的弹性搜索性能问题
使用弹性“数字”:“6.3.1” “lucene_版本”:“7.3.1” 嵌套:6.1.0 正在尝试翻译下面的搜索。本质上,message1、message2可以有空字符串值。如果search1Value或search2Value是空字符串,我不希望为存在空字符串的部分或条件返回任何记录 这篇文章是一个更大的搜索与其他条件的一部分。。。但是这段代码导致查询速度非常慢。在创建索引时,除了原始字段之外,我还创建了原始字段,以便能够搜索非空字段。我尝试过的其他方法都不允许我正确地进行搜索。有没有其他方法可以做到这一点?如前所述,查询的性能非常糟糕。超过2秒。该索引有大约60万个文档。不过,这种逻辑确实有效。它确实返回了正确的文档 提前感谢您的帮助elasticsearch 嵌套:由于空搜索而导致的弹性搜索性能问题,elasticsearch,nest,elasticsearch,Nest,使用弹性“数字”:“6.3.1” “lucene_版本”:“7.3.1” 嵌套:6.1.0 正在尝试翻译下面的搜索。本质上,message1、message2可以有空字符串值。如果search1Value或search2Value是空字符串,我不希望为存在空字符串的部分或条件返回任何记录 这篇文章是一个更大的搜索与其他条件的一部分。。。但是这段代码导致查询速度非常慢。在创建索引时,除了原始字段之外,我还创建了原始字段,以便能够搜索非空字段。我尝试过的其他方法都不允许我正确地进行搜索。有没有其他方
message1 != "" and message1.StartsWith(search1Value)
OR
message2 != "" and message2.StartsWith(search2Value)
所以如果索引中的可用文档示例
id, message1, message2
1, "", "abc"
2, "", ""
3, "def", ""
4, "", "ghi"
如果searchValue1是空字符串,而searchValue2是abc,则我想返回,只记录1。不是记录1、2和4
为了在此条件下正确搜索,设置了如下索引:
public class MessageSearch() {
public string Message1 {get; set;}
public string Message2 {get; set;}
}
public class MessageModelIndex() {
public string Message1 {get; set;} = ""
public string Message2 {get; set;} = ""
}
public override CreateIndexDescriptor DefineIndex(string indexName)
{
return new CreateIndexDescriptor(indexName).Settings(s => s
.NumberOfShards(2)
.Mappings(ms => ms
.Map<MessageModelIndex>(m => m
.Properties(p => p
.Text(s => s
.Name(x => x.Message1)
.Fields(ff => ff
.Text(tt => tt
.Name("raw")
)
.Keyword(k => k
.Name("keyword")
.IgnoreAbove(1)
)
)
)
.Text(s => s
.Name(x => x.Message2)
.Fields(ff => ff
.Text(tt => tt
.Name("raw")
)
.Keyword(k => k
.Name("keyword")
.IgnoreAbove(1)
)
)
)
)
));
}
public class MessageSearch(){
公共字符串Message1{get;set;}
公共字符串Message2{get;set;}
}
公共类MessageModelIndex(){
公共字符串Message1{get;set;}=“”
公共字符串Message2{get;set;}=“”
}
公共重写CreateIndexDescriptor DefineIndex(字符串indexName)
{
返回新的CreateIndexDescriptor(indexName).Settings(s=>s
.NumberOfShard(2)
.Mappings(ms=>ms
.Map(m=>m
.Properties(p=>p
.Text(s=>s
.Name(x=>x.Message1)
.Fields(ff=>ff
.Text(tt=>tt
.名称(“原始”)
)
.Keyword(k=>k
.Name(“关键字”)
.Ignore(1)
)
)
)
.Text(s=>s
.Name(x=>x.Message2)
.Fields(ff=>ff
.Text(tt=>tt
.名称(“原始”)
)
.Keyword(k=>k
.Name(“关键字”)
.Ignore(1)
)
)
)
)
));
}
以下搜索用于获取这些值:
public void PerformSearch(MessageSearch search) {
var result = _client.Search<MessageModelIndex>(x => x
.Index("MessageTest")
.Size(1000)
.Query(q => q
.Bool(b => b
.Must(bm => bm
.Bool(bb => bb
.Should(bbs => bbs
.Bool(bbb => bbb
.Must(mm => mm
.Bool(bbbb => bbbb
.MustNot(bbbmn => bbbmn.Term(t => t.Verbatim().Field(f => f.Message1.Suffix("keyword")).Value(string.Empty)))
),
mm => mm
.Bool(bbbb => bbbb
.Must(bbbmn => bbbmn.MatchPhrasePrefix(mmp => mmp.Query(search.Message1.Trim()).Field(f => f.Message1.Suffix("raw"))))
)
)
), bbs => bbs
.Bool(bbb => bbb
.Must(mm => mm
.Bool(bbbb => bbbb
.MustNot(bbbmn => bbbmn.Term(t => t.Verbatim().Field(f => f.Message2.Suffix("keyword")).Value(string.Empty)))
),
mm => mm
.Bool(bbbb => bbbb
.Must(bbbmn => bbbmn.MatchPhrasePrefix(mmp => mmp.Query(search.Message2.Trim()).Field(f => f.Message2.Suffix("raw"))))
)
)
)
)
)
)
)
)
);
}
public void性能搜索(MessageSearch){
var result=\u client.Search(x=>x
.Index(“MessageTest”)
.尺寸(1000)
.Query(q=>q
.Bool(b=>b
.Must(bm=>bm
.Bool(bb=>bb
.Should(bbs=>bbs
.Bool(bbb=>bbb
.Must(mm=>mm
.Bool(bbbb=>bbbb
.MustNot(bbbmn=>bbbmn.Term(t=>t.Verbatim().Field(f=>f.Message1.Suffix(“关键字”)).Value(string.Empty)))
),
mm=>mm
.Bool(bbbb=>bbbb
.Must(bbbmn=>bbbmn.MatchPhrasePrefix(mmp=>mmp.Query(search.Message1.Trim()).Field(f=>f.Message1.Suffix(“原始”))
)
)
),bbs=>bbs
.Bool(bbb=>bbb
.Must(mm=>mm
.Bool(bbbb=>bbbb
.MustNot(bbbmn=>bbbmn.Term(t=>t.Verbatim().Field(f=>f.Message2.Suffix(“关键字”)).Value(string.Empty)))
),
mm=>mm
.Bool(bbbb=>bbbb
.Must(bbbmn=>bbbmn.MatchPhrasePrefix(mmp=>mmp.Query(search.Message2.Trim()).Field(f=>f.Message2.Suffix(“原始”))
)
)
)
)
)
)
)
)
);
}
映射和查询对于您想要的结果来说似乎不正确。让我们将其分解
在创建索引时,我除了创建原始字段外,还创建了原始字段,以便能够搜索非空字段。我尝试过的任何其他方法都不允许我正确执行该搜索。是否有其他方法可以执行此操作
映射
例如,您拥有的映射
.Text(s=>s)
.Name(x=>x.Message1)
.Fields(ff=>ff
.Text(tt=>tt
.名称(“原始”)
)
.Keyword(k=>k
.Name(“关键字”)
白痴
.Bool(b => b
.Must(bm => bm
.Bool(bb => bb
.Should(bbs => bbs
.Bool(bbb => bbb
.Must(mm => mm
.Bool(bbbb => bbbb
.MustNot(bbbmn => bbbmn.Term(t => t.Verbatim().Field(f => f.Message1.Suffix("keyword")).Value(string.Empty)))
),
mm => mm
.Bool(bbbb => bbbb
.Must(bbbmn => bbbmn.MatchPhrasePrefix(mmp => mmp.Query(search.Message1.Trim()).Field(f => f.Message1.Suffix("raw"))))
)
)
)
var bulkResponse = client.Bulk(b => b
.IndexMany(new []
{
new MessageModelIndex { Id = 1, Message1 = "", Message2 = "abc" },
new MessageModelIndex { Id = 2, Message1 = "", Message2 = "" },
new MessageModelIndex { Id = 3, Message1 = "def", Message2 = "" },
new MessageModelIndex { Id = 4, Message1 = "", Message2 = "ghi" },
})
.Refresh(Refresh.WaitFor)
);
var emptyStringInputResponse = client.Search<MessageModelIndex>(x => x
.Index(defaultIndex)
.Query(q => q
.MatchPhrasePrefix(t => t
.Verbatim()
.Field(f => f.Message1)
.Query("")
)
)
);
var searchResponse = client.Search<MessageModelIndex>(x => x
.Index(defaultIndex)
.Size(1000)
.Query(q => q
.Bool(bb => bb
.Should(bbs => bbs
.MatchPhrasePrefix(mmp => mmp
.Query(search.Message1.Trim())
.Field(f => f.Message1)
), bbs => bbs
.MatchPhrasePrefix(mmp => mmp
.Query(search.Message2.Trim())
.Field(f => f.Message2)
)
)
)
)
);
var searchResponse = client.Search<MessageModelIndex>(x => x
.Index(defaultIndex)
.Size(1000)
.Query(q => q
.MatchPhrasePrefix(mmp => mmp
.Query(search.Message1.Trim())
.Field(f => f.Message1)
) || q
.MatchPhrasePrefix(mmp => mmp
.Query(search.Message2.Trim())
.Field(f => f.Message2)
)
)
);
private static void Main()
{
var defaultIndex = "message-test";
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var settings = new ConnectionSettings(pool)
.DefaultIndex(defaultIndex);
var client = new ElasticClient(settings);
if (client.IndexExists(defaultIndex).Exists)
client.DeleteIndex(defaultIndex);
client.CreateIndex(defaultIndex, c => c
.Mappings(m => m
.Map<MessageModelIndex>(mm => mm
.Properties(p => p
.Text(s => s
.Name(x => x.Message1)
.Fields(ff => ff
.Keyword(k => k
.Name("keyword")
.IgnoreAbove(0)
)
)
)
.Text(s => s
.Name(x => x.Message2)
.Fields(ff => ff
.Keyword(k => k
.Name("keyword")
.IgnoreAbove(0)
)
)
)
)
)
)
);
var bulkResponse = client.Bulk(b => b
.IndexMany(new []
{
new MessageModelIndex { Id = 1, Message1 = "", Message2 = "abc" },
new MessageModelIndex { Id = 2, Message1 = "", Message2 = "" },
new MessageModelIndex { Id = 3, Message1 = "def", Message2 = "" },
new MessageModelIndex { Id = 4, Message1 = "", Message2 = "ghi" },
})
.Refresh(Refresh.WaitFor)
);
var search = new MessageSearch
{
Message1 = "",
Message2 = "abc"
};
var searchResponse = client.Search<MessageModelIndex>(x => x
.Index(defaultIndex)
.Size(1000)
.Query(q => q
.MatchPhrasePrefix(mmp => mmp
.Query(search.Message1.Trim())
.Field(f => f.Message1)
) || q
.MatchPhrasePrefix(mmp => mmp
.Query(search.Message2.Trim())
.Field(f => f.Message2)
)
)
);
}
public class MessageSearch
{
public string Message1 { get; set; }
public string Message2 { get; set; }
}
public class MessageModelIndex
{
public int Id { get; set; }
public string Message1 { get; set; } = "";
public string Message2 { get; set; } = "";
}