为了账号安全,请及时绑定邮箱和手机立即绑定

Elasticsearch嵌套数组的多个过滤条件

Elasticsearch嵌套数组的多个过滤条件

C#
MMMHUHU 2023-08-20 11:05:39
也许这个问题在某处得到了回答,但我找不到它。所以我寻求帮助我的产品模型有一个嵌套的属性列表。像这样的东西[    {        ID: "Product1",        ...        Properties: [            { "Source": "Color", Value: "green"},            { "Source": "Size",  Value: "2"},        ]    },    {        ID: "Product2",        ...        Properties: [            { "Source": "Color", Value: "blue"},            { "Source": "Size", Value: "2"},        ]    },    {        ID: "Product3",        ....        Properties: [            { "Source": "Color", Value: "red"},            { "Source": "Size", Value: "1"},        ]    },]索引映射:"properties" : {        "type" : "nested",        "properties" : {          "source" : {            "type" : "text",            "fields" : {              "keyword" : {                "type" : "keyword",                "ignore_above" : 256              }            }          },          "value" : {            "type" : "text",            "fields" : {              "keyword" : {                "type" : "keyword",                "ignore_above" : 256              }            }          }        }      },我需要搜索查询来仅查找颜色为绿色或蓝色且尺寸为 2 的产品。我为我的搜索请求创建了此查询,但它将返回空结果。您能帮助我构建这种查询,我用错了什么吗?谢谢
查看完整描述

1 回答

?
侃侃尔雅

TA贡献1801条经验 获得超15个赞

尝试用嵌套查询包装每个必须子句:


var query = new BoolQuery

{

    Must = new QueryContainer[]

    {

        new NestedQuery

        {

            Path = "properties",

            Query = new BoolQuery()

            {

                Must = new QueryContainer[]

                {

                    new TermQuery()

                    {

                        Field = new Nest.Field("properties.source.keyword"),

                        Value = "Color"

                    },

                    new TermsQuery()

                    {

                        Field = new Nest.Field("properties.value.keyword"),

                        Terms = new[] { "green", "blue"}

                    }

                }

            }

        },

        new NestedQuery

        {

            Path = "properties",

            Query = new BoolQuery()

            {

                Must = new QueryContainer[]

                {

                    new TermQuery()

                    {

                        Field = new Nest.Field("properties.source.keyword"),

                        Value = "Size"

                    },

                    new TermsQuery()

                    {

                        Field = new Nest.Field("properties.value.keyword"),

                        Terms = new[] {"2"}

                    }

                }

            }

        }

    }

};

完整的工作示例


class Program

{

    public class Document

    {

        public int Id { get; set; }

        [Nested]

        public List<Property> Properties { get; set; }

    }


    public class Property

    {

        public string Source { get; set; }

        public string Value { get; set; }


        public override string ToString() => $"Source: {Source} Value: {Value}";

    }


    static async Task Main(string[] args)

    {

        var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));

        var connectionSettings = new ConnectionSettings(pool);

        connectionSettings.DefaultIndex("documents");

        connectionSettings.DisableDirectStreaming();

        connectionSettings.PrettyJson();


        var client = new ElasticClient(connectionSettings);


        var deleteIndexResponse = await client.Indices.DeleteAsync("documents");

        var createIndexResponse = await client.Indices.CreateAsync("documents", d => d

            .Map(m => m.AutoMap<Document>()));


        var indexDocument = await client

            .IndexDocumentAsync(new Document

            {

                Id = 1, 

                Properties = new List<Property>

                {

                    new Property {Source = "Color", Value = "green"},

                    new Property {Source = "Size", Value = "2"},

                }

            });

        indexDocument = await client

            .IndexDocumentAsync(new Document

            {

                Id = 2, 

                Properties = new List<Property>

                {

                    new Property {Source = "Color", Value = "blue"},

                    new Property {Source = "Size", Value = "2"},

                }

            });

        indexDocument = await client

            .IndexDocumentAsync(new Document

            {

                Id = 3, 

                Properties = new List<Property>

                {

                    new Property {Source = "Color", Value = "red"},

                    new Property {Source = "Size", Value = "1"},

                }

            });


        var refreshAsync = client.Indices.RefreshAsync();


        var query = new BoolQuery

        {

            Must = new QueryContainer[]

            {

                new NestedQuery

                {

                    Path = "properties",

                    Query = new BoolQuery()

                    {

                        Must = new QueryContainer[]

                        {

                            new TermQuery()

                            {

                                Field = new Nest.Field("properties.source.keyword"),

                                Value = "Color"

                            },

                            new TermsQuery()

                            {

                                Field = new Nest.Field("properties.value.keyword"),

                                Terms = new[] {"green", "blue"}

                            }

                        }

                    }

                },

                new NestedQuery

                {

                    Path = "properties",

                    Query = new BoolQuery()

                    {

                        Must = new QueryContainer[]

                        {

                            new TermQuery()

                            {

                                Field = new Nest.Field("properties.source.keyword"),

                                Value = "Size"

                            },

                            new TermsQuery()

                            {

                                Field = new Nest.Field("properties.value.keyword"),

                                Terms = new[] {"2"}

                            }

                        }

                    }

                }

            }

        };


        var response = client.Search<Document>(s => s.Query(q => query));


        foreach (var document in response.Documents)

        {

            Console.WriteLine($"Id: {document.Id}");

            document.Properties.ForEach(Console.WriteLine);

            Console.WriteLine();

        }

    }

}

印刷:


Id: 1

Source: Color Value: green

Source: Size Value: 2


Id: 2

Source: Color Value: blue

Source: Size Value: 2

希望有帮助。


查看完整回答
反对 回复 2023-08-20
  • 1 回答
  • 0 关注
  • 87 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信