Using Elastic "number": "6.3.1" "lucene_version": "7.3.1" NEST: 6.1.0
Trying to translate the below search. Essentially message1, message2 can have empty string values. if search1Value or search2Value is empty string, i don't want any records returned for that part of the OR condition where there is an empty string.
This piece is part of a much large Search with other criteria... BUT this piece is causing the Query to ES to be extremely SLOW. I create RAW fields in addition to the original fields when creating the index just to be able to search on NOT EMPTY. Nothing else i had tried allowed me to do that search correctly. IS there a different way to do this? As mentioned the performance of the query is Terrible. Over 2secs. The index in question have around 600k documents. The logic DOES work though. It does return the correct documents.
Thank you in advance for any assistance!!
message1 != "" and message1.StartsWith(search1Value)
OR
message2 != "" and message2.StartsWith(search2Value)
so if example of available docs in index...
id, message1, message2
1, "", "abc"
2, "", ""
3, "def", ""
4, "", "ghi"
if searchValue1 is empty string, and searchValue2 is abc i want to get back, only record 1. Not record 1, 2, and 4.
in order to properly search on this condition an index was setup as such:
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)
)
)
)
)
));
}
The following Search is used to get these values:
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"))))
)
)
)
)
)
)
)
)
);
}