elasticsearch 使用嵌套进行搜索时未产生预期结果,elasticsearch,nest,elasticsearch,Nest" /> elasticsearch 使用嵌套进行搜索时未产生预期结果,elasticsearch,nest,elasticsearch,Nest" />

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;
}