elasticsearch 使用嵌套进行搜索时未产生预期结果
我正在使用以下代码创建索引:elasticsearch 使用嵌套进行搜索时未产生预期结果,elasticsearch,nest,elasticsearch,Nest,我正在使用以下代码创建索引: var ElasticSettings = new ConnectionSettings(new Uri(ConnectionString)) .DefaultIndex(_IndexName) .DefaultMappingFor<PictureObject>(M => M .Ignore(_ => _._id) .Ignore(_ =&
var ElasticSettings = new ConnectionSettings(new Uri(ConnectionString))
.DefaultIndex(_IndexName)
.DefaultMappingFor<PictureObject>(M => M
.Ignore(_ => _._id)
.Ignore(_ => _.Log))
.DefaultFieldNameInferrer(_ => _);
_ElasticClient = new ElasticClient(ElasticSettings);
if (!_ElasticClient.IndexExists(_IndexName).Exists)
{
var I = _ElasticClient.CreateIndex(_IndexName, Ci => Ci
.Settings(S => S
.Analysis(A => A
.CharFilters(Cf => Cf.Mapping("expressions",
E => E.Mappings(ExpressionsList))
)
.TokenFilters(Tf => Tf.Synonym("synonyms",
Descriptor => new SynonymTokenFilter
{
Synonyms = SynonymsList,
Tokenizer = "whitespace"
})
)
.Analyzers(Analyzer => Analyzer
.Custom("index", C => C
.CharFilters("expressions")
.Tokenizer("standard")
.Filters("synonyms", "standard", "lowercase", "stop")
)
.Custom("search", C => C
.CharFilters("expressions")
.Tokenizer("standard")
.Filters("synonyms", "standard", "lowercase", "stop")
)
)
)
)
.Mappings(Mapping => Mapping
.Map<PictureObject>(Map => Map
.AutoMap()
.Properties(P => P
.Text(T => T
.Name(N => N.Title)
.Analyzer("index")
.SearchAnalyzer("search")
)
.Text(T => T
.Name(N => N.Tags)
.Analyzer("index")
.SearchAnalyzer("search")
)
)
)
)
);
var ElasticSettings=新连接设置(新Uri(ConnectionString))
.DefaultIndex(_IndexName)
.DefaultMappingFor(M=>M
.Ignore(=>u.u id)
.Ignore(=>.Log))
.DefaultFieldNameInferrer(\u=>\ u0);
_ElasticClient=新的ElasticClient(ElasticSettings);
如果(!\u ElasticClient.indexists(\u IndexName.Exists)
{
var I=\u ElasticClient.CreateIndex(\u IndexName,Ci=>Ci
.Settings(S=>S
.分析(A=>A
.CharFilters(Cf=>Cf.Mapping(“表达式”),
E=>E.Mappings(表达式列表))
)
.TokenFilters(Tf=>Tf.Synonym(“同义词”),
描述符=>新的同义词过滤器
{
同义词=同义词列表,
标记器=“空白”
})
)
.分析仪(分析仪=>Analyzer
.自定义(“索引”,C=>C
.CharFilters(“表达式”)
.Tokenizer(“标准”)
.过滤器(“同义词”、“标准”、“小写”、“停止”)
)
.Custom(“搜索”,C=>C
.CharFilters(“表达式”)
.Tokenizer(“标准”)
.过滤器(“同义词”、“标准”、“小写”、“停止”)
)
)
)
)
.Mappings(映射=>Mapping
.Map(Map=>Map
.AutoMap()
.Properties(P=>P
.Text(T=>T
.Name(N=>N.Title)
.Analyzer(“索引”)
.SearchAnalyzer(“搜索”)
)
.Text(T=>T
.Name(N=>N.Tags)
.Analyzer(“索引”)
.SearchAnalyzer(“搜索”)
)
)
)
)
);
我要搜索的字段是“title”和“tags”
我的同义词就是这种格式:
[“大=>大,大”,“小=>小,小”
我的表情是:
[“暴风雨天气=>暴风雨”,“快乐日=>欢乐”,]
我使用以下两种方法进行测试:
var Test1 = _ElasticClient.Search<PictureObject>(S => S
.From(From)
.Size(Take)
.Query(_ => _.Fuzzy(Fuzz => Fuzz.Field(F => F.Tags).Field(T => T.Title).Value(Terms).MaxExpansions(2)))).Documents;
var resTest2 = _ElasticClient.Search<PictureObject>(S => S
.Query(_ => _.QueryString(F => F.Query(Terms)))
.From(From)
.Size(Take));
var Test1=\u ElasticClient.Search(S=>S
.从(从)
.尺寸(取)
.Query(=>Fuzz.Fuzzy(Fuzz=>Fuzz.Field(F=>F.Tags).Field(T=>T.Title).Value(Terms.MaxExpansions(2)))).Documents;
var resTest2=\u ElasticClient.Search(S=>S
.Query(=>QueryString(F=>F.Query(Terms)))
.从(从)
.尺寸(取);
当尝试完全匹配标记字段中的术语时,这两个函数返回不同的结果。
当尝试使用同义词时,结果会再次发生变化
(最终,我也想处理拼写错误,但目前我只使用逐字字符串进行测试)
我遗漏了什么?(我对API的理解仍然很模糊,因此错误可能非常明显)
编辑:
下面是一个可以编译的完整工作示例
namespace Test
{
using System;
using System.Collections.Generic;
using Nest;
public class MyData
{
public string Id;
public string Title;
public string Tags;
}
public static class Program
{
public static void Main()
{
const string INDEX_NAME = "testindex";
var ExpressionsList = new[]
{
"bad weather => storm",
"happy day => sun"
};
var SynonymsList = new[]
{
"big => large, huge",
"small => tiny, minuscule",
"sun => sunshine, shiny, sunny"
};
// connect
var ElasticSettings = new ConnectionSettings(new Uri("http://elasticsearch:9200"))
.DefaultIndex(INDEX_NAME)
.DefaultFieldNameInferrer(_ => _) // stop the camel case
.DefaultMappingFor<MyData>(M => M.IdProperty("Id"));
var Client = new ElasticClient(ElasticSettings);
// erase the old index, if any
if (Client.IndexExists(INDEX_NAME).Exists) Client.DeleteIndex(INDEX_NAME);
// create the index
var I = Client.CreateIndex(INDEX_NAME, Ci => Ci
.Settings(S => S
.Analysis(A => A
.CharFilters(Cf => Cf.Mapping("expressions",
E => E.Mappings(ExpressionsList))
)
.TokenFilters(Tf => Tf.Synonym("synonyms",
Descriptor => new SynonymTokenFilter
{
Synonyms = SynonymsList,
Tokenizer = "whitespace"
})
)
.Analyzers(Analyzer => Analyzer
.Custom("index", C => C
.CharFilters("expressions")
.Tokenizer("standard")
.Filters("synonyms", "standard", "lowercase", "stop")
)
.Custom("search", C => C
.CharFilters("expressions")
.Tokenizer("standard")
.Filters("synonyms", "standard", "lowercase", "stop")
)
)
)
)
.Mappings(Mapping => Mapping
.Map<MyData>(Map => Map
.AutoMap()
.Properties(P => P
.Text(T => T
.Name(N => N.Title)
.Analyzer("index")
.SearchAnalyzer("search")
)
.Text(T => T
.Name(N => N.Tags)
.Analyzer("index")
.SearchAnalyzer("search")
)
)
)
)
);
// add some data
var Data = new List<MyData>
{
new MyData { Id = "1", Title = "nice stormy weather", Tags = "storm nice" },
new MyData { Id = "2", Title = "a large storm with sunshine", Tags = "storm large sunshine" },
new MyData { Id = "3", Title = "a storm during a sunny day", Tags = "sun storm" }
};
Client.IndexMany(Data);
Client.Refresh(INDEX_NAME);
// do some queries
var TestA1 = Client.Search<MyData>(S => S.Query(_ => _.Fuzzy(Fuzz => Fuzz.Field(F => F.Tags).Field(T => T.Title).Value("stormy sunny").MaxExpansions(2)))).Documents;
var TestA2 = Client.Search<MyData>(S => S.Query(_ => _.Fuzzy(Fuzz => Fuzz.Field(F => F.Tags).Field(T => T.Title).Value("stromy sunny").MaxExpansions(2)))).Documents;
var TestB1 = Client.Search<MyData>(S => S.Query(_ => _.QueryString(F => F.Query("stormy sunny")))).Documents;
// expected to return documents 1, 2, 3 because of synonyms: sun => sunny, shiny, sunshine
var TestB2 = Client.Search<MyData>(S => S.Query(_ => _.QueryString(F => F.Query("bad weather")))).Documents;
var TestB3 = Client.Search<MyData>(S => S.Query(_ => _.QueryString(F => F.Query("a large happy day")))).Documents;
/*
* I'm expecting the fuzzy queries to handle misspellings
* Also, I'm expecting the expressions and synonyms to do the substitutions as they're written
*
* Ideally I'd like to handle:
* - expressions
* - synonyms
* - misspellings
*
* all together
*
* I have tried a lot of string examples while debugging and it's really hit or miss.
* Unfortunately, I haven't kept the strings, but it was enough to see that there is something
* wrong with my approach in this code.
*/
}
}
}
名称空间测试
{
使用制度;
使用System.Collections.Generic;
利用鸟巢;
公共类MyData
{
公共字符串Id;
公共字符串标题;
公共字符串标签;
}
公共静态类程序
{
公共静态void Main()
{
常量字符串索引\u NAME=“testindex”;
var ExpressionsList=new[]
{
“恶劣天气=>暴风雨”,
“快乐日=>太阳”
};
var同义词列表=新[]
{
“大=>大,大”,
“小=>小,小”,
“阳光=>阳光,闪亮,阳光”
};
//连接
var ElasticSettings=新连接设置(新Uri(“http://elasticsearch:9200"))
.DefaultIndex(索引名称)
.DefaultFieldNameInferrer(\u=>\ u7)//停止驼峰大小写
.DefaultMappingFor(M=>M.IdProperty(“Id”);
var客户端=新的ElasticClient(ElasticSettings);
//删除旧索引(如果有)
if(Client.indexists(INDEX\u NAME).Exists)Client.DeleteIndex(INDEX\u NAME);
//创建索引
var I=Client.CreateIndex(索引名称,Ci=>Ci
.Settings(S=>S
.分析(A=>A
.CharFilters(Cf=>Cf.Mapping(“表达式”),
E=>E.Mappings(表达式列表))
)
.TokenFilters(Tf=>Tf.Synonym(“同义词”),
描述符=>新的同义词过滤器
{
同义词=同义词列表,
标记器=“空白”
})
)
.分析仪(分析仪=>Analyzer
.自定义(“索引”,C=>C
.CharFilters(“表达式”)
.Tokenizer(“标准”)
.过滤器(“同义词”、“标准”、“小写”、“停止”)
)
.Custom(“搜索”,C=>C
.CharFilters(“表达式”)
.Tokenizer(“标准”)
.过滤器(“同义词”、“标准”、“小写”、“停止”)
)
)
)
)
.Mappings(映射=>
var ExpressionsList = new[]
{
"bad weather => storm",
"happy day => sun"
};
var SynonymsList = new[]
{
"big => large, huge",
"small => tiny, minuscule",
"sun => sunshine, shiny, sunny"
};
var SynonymsList = new[]
{
"big, large, huge",
"small, tiny, minuscule",
"sun, sunshine, shiny, sunny"
};
var TestB1 = Client.Search<MyData>(S => S.Query(_ => _.QueryString(F => F.Query("stormy sunny")))).Documents;
// expected to return documents 1, 2, 3 because of synonyms: sun => sunny, shiny, sunshine
.Custom("index", C => C
.CharFilters("expressions")
.Tokenizer("standard")
.Filters("synonyms", "standard", "lowercase", "stop")
)
.Custom("search", C => C
.CharFilters("expressions")
.Tokenizer("standard")
.Filters("synonyms", "standard", "lowercase", "stop")
)
public class MyData
{
public string Id;
public string Title;
public string Tags;
}
public static void Main()
{
const string INDEX_NAME = "testindex";
var expressions = new[]
{
"bad weather => storm",
"happy day => sun"
};
var synonyms = new[]
{
"big, large, huge",
"small, tiny, minuscule",
"sun, sunshine, shiny, sunny"
};
// connect
var settings = new ConnectionSettings(new Uri("http://localhost:9200"))
.DefaultIndex(INDEX_NAME)
.DefaultFieldNameInferrer(s => s) // stop the camel case
.DefaultMappingFor<MyData>(m => m.IdProperty("Id"))
.DisableDirectStreaming()
.PrettyJson()
.OnRequestCompleted(callDetails =>
{
if (callDetails.RequestBodyInBytes != null)
{
Console.WriteLine(
$"{callDetails.HttpMethod} {callDetails.Uri} \n" +
$"{Encoding.UTF8.GetString(callDetails.RequestBodyInBytes)}");
}
else
{
Console.WriteLine($"{callDetails.HttpMethod} {callDetails.Uri}");
}
Console.WriteLine();
if (callDetails.ResponseBodyInBytes != null)
{
Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
$"{Encoding.UTF8.GetString(callDetails.ResponseBodyInBytes)}\n" +
$"{new string('-', 30)}\n");
}
else
{
Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
$"{new string('-', 30)}\n");
}
});
var Client = new ElasticClient(settings);
// erase the old index, if any
if (Client.IndexExists(INDEX_NAME).Exists) Client.DeleteIndex(INDEX_NAME);
// create the index
var createIndexResponse = Client.CreateIndex(INDEX_NAME, c => c
.Settings(s => s
.Analysis(a => a
.CharFilters(cf => cf
.Mapping("expressions", E => E
.Mappings(expressions)
)
)
.TokenFilters(tf => tf
.Synonym("synonyms", sy => sy
.Synonyms(synonyms)
.Tokenizer("whitespace")
)
)
.Analyzers(an => an
.Custom("index", ca => ca
.CharFilters("expressions")
.Tokenizer("standard")
.Filters("standard", "lowercase", "synonyms", "stop")
)
)
)
)
.Mappings(m => m
.Map<MyData>(mm => mm
.AutoMap()
.Properties(p => p
.Text(t => t
.Name(n => n.Title)
.Analyzer("index")
)
.Text(t => t
.Name(n => n.Tags)
.Analyzer("index")
)
)
)
)
);
// add some data
var data = new List<MyData>
{
new MyData { Id = "1", Title = "nice stormy weather", Tags = "storm nice" },
new MyData { Id = "2", Title = "a large storm with sunshine", Tags = "storm large sunshine" },
new MyData { Id = "3", Title = "a storm during a sunny day", Tags = "sun storm" }
};
Client.IndexMany(data);
Client.Refresh(INDEX_NAME);
//var query = "stormy sunny";
var query = "stromy sunny";
// var query = "bad weather";
// var query = "a large happy day";
var testA1 = Client.Search<MyData>(s => s
.Query(q => q
.MultiMatch(fu => fu
.Fields(f => f
.Field(ff => ff.Tags)
.Field(ff => ff.Title)
)
.Query(query)
.Fuzziness(Fuzziness.EditDistance(2))
)
)
).Documents;
}