Elastic Search嵌套多重匹配查询

Elastic Search嵌套多重匹配查询

C# 代码写的查询Elastic Search,多值查询如何写?

实体类如下:

/// <summary>
    /// 图像信息类
    /// </summary>
    public class CustomCTImageInfo
    {
        [Text(Name = "PRN")]
        public string PRN { get; set; }

      
        [Number(NumberType.Integer, Name = "ImageMode")]
        public uint ImageMode { get; set; }

        [Nested]
        [PropertyName("Judges")]
        public List<JudgeConclusion> Judges { get; set; }

        [Nested]
        [PropertyName("Checks")]
        public List<CheckConclusion> Checks { get; set; }

        [Nested]
        [PropertyName("AiSusDatas")]
        public List<AiSusData> AiSusDatas { get; set; }
}
 public class AiSusData
    {
        [Date(Name = "RecvTime")]
        public DateTime RecvTime { get; set; }

        [Number(NumberType.Integer, Name = "TypeID")]
        public int TypeID { get; set; } 

        [Text(Name = "TypeName")]
        public string TypeName { get; set; } 

        [Number(NumberType.Integer, Name = "SubTypeID")]
        public int SubTypeID { get; set; }

        [Text(Name = "SubTypeName")]
        public string SubTypeName { get; set; } 

        [Number(NumberType.Integer, Name = "Count")]
        public int Count { get; set; } 

        [Number(NumberType.Integer, Name = "HandleType")]
        public int HandleType { get; set; } 

        [Text(Name = "Description")]
        public string Description { get; set; } 
     
    }

查询AiSusData 中的SubTypeID 在数组中(相当于SQL语句中的 IN)



var response = ESClient.Search<CustomCTImageInfo>(s => s.From((request.CurrentPage - 1)* request.PageSize).Size(request.PageSize)
               .Sort(i => i.Descending(f => f.CreateTime))
               .TrackTotalHits()
               .Query(query: q => q.Bool(m => m.Must(
                  
                   fs => fs.Bool(sh=>sh.Should(
                     
                        f =>
                        {
                            return f.Nested(
                                l => l.Path(j => j.AiSusDatas).Query(p => p.Bool(k => k.Must(
                                    h =>
                                    {
                                        if (string.IsNullOrEmpty(request.AISusDataId.ToString()) ||
                                            request.AISusDataId.ToString().Equals("-1"))
                                        {
                                            return new QueryContainer();
                                        }



                                   **     return h.Terms(o =>
                                          o.Field(n => n.AiSusDatas.First().SubTypeID)
                                              .Terms(AISusDataArray));__**
                                    }

                                )))
                            );


                        }
                       ))


最后的 AiSusDatas 筛选该如何写?


在C#中,使用NEST库可以方便地与Elasticsearch进行交互。对于嵌套的多重匹配查询,你可以使用BoolQuery来构建。

以下是一个示例代码,它展示了如何使用NEST库进行嵌套的多重匹配查询:

using Nest;
using System;

public class Example
{
    public void Search()
    {
        var client = new ElasticClient();

        var searchRequest = new SearchRequest("your_index")
        {
            Query = new BoolQuery
            {
                Must = new QueryContainer[]
                {
                    new MultiMatchQuery
                    {
                        Fields = new[] { "field1", "field2" },
                        Query = "your_query"
                    },
                    new BoolQuery
                    {
                        Must = new QueryContainer[]
                        {
                            new TermQuery { Field = "field3", Value = "term1" },
                            new TermQuery { Field = "field4", Value = "term2" }
                        }
                    }
                }
            }
        };

        var result = client.Search<YourType>(searchRequest);
        // 处理结果...
    }
}

在这个例子中,我们首先创建了一个SearchRequest,指定了要查询的索引。然后,我们设置QueryBoolQuery,其中包含两个Must条件:一个MultiMatchQuery和另一个BoolQuery。这个BoolQuery又包含两个TermQuery条件。你可以根据需要添加更多的条件。

注意,你需要将"your_index"、"your_query"、"field1"、"field2"、"field3"和"field4"替换为你的实际值。同时,你需要将YourType替换为你的数据类型的名字。这个类型应该匹配你在Elasticsearch中存储的数据的类型。

引用 皆我百晓生 小程序回复内容作答:
在上述代码中,您可以使用Terms查询来筛选AiSusDatas中的SubTypeID字段。您可以将筛选条件作为参数传递给Terms方法,并指定要匹配的数组值。以下是如何修改您的代码:

var response = ESClient.Search<CustomCTImageInfo>(s => s
    .From((request.CurrentPage - 1) * request.PageSize)
    .Size(request.PageSize)
    .Sort(i => i.Descending(f => f.CreateTime))
    .TrackTotalHits()
    .Query(query: q => q.Bool(m => m.Must(
        fs => fs.Bool(sh => sh.Should(
            f =>
            {
                return f.Nested(
                    l => l.Path(j => j.AiSusDatas).Query(p => p.Bool(k => k.Must(
                        h =>
                        {
                            if (string.IsNullOrEmpty(request.AISusDataId.ToString()) ||
                                request.AISusDataId.ToString().Equals("-1"))
                            {
                                return new QueryContainer();
                            }

                            return h.Nested(n => n.Path(j => j.AiSusDatas).Query(m => m.Terms(t => t
                                .Field(f => f.AiSusDatas[0].SubTypeID)
                                .Terms(AISusDataArray)
                            )));
                        }
                    ))));
            }
        )))));

请注意,将AiSusDatas.First().SubTypeID替换为AiSusDatas[0].SubTypeID以确保正确匹配SubTypeID字段。

引用chatgpt内容作答:
要在Elasticsearch中执行嵌套多重匹配查询,您可以使用Nested查询来处理嵌套字段。在您的情况下,您想要查询AiSusData的SubTypeID是否在一个数组中,类似于SQL中的IN操作。您可以使用Terms查询来实现这一点。以下是如何修改您的C#代码以执行此查询:

var response = ESClient.Search<CustomCTImageInfo>(s => s.From((request.CurrentPage - 1) * request.PageSize).Size(request.PageSize)
    .Sort(i => i.Descending(f => f.CreateTime))
    .TrackTotalHits()
    .Query(query: q => q.Bool(m => m.Must(
        fs => fs.Bool(sh => sh.Should(
            f =>
            {
                return f.Nested(
                    l => l.Path(j => j.AiSusDatas).Query(p => p.Bool(k => k.Must(
                        h =>
                        {
                            if (string.IsNullOrEmpty(request.AISusDataId.ToString()) ||
                                request.AISusDataId.ToString().Equals("-1"))
                            {
                                return new QueryContainer();
                            }

                            return h.Nested(n => n
                                .Path("AiSusDatas")
                                .Query(nq => nq
                                    .Terms(t => t
                                        .Field("AiSusDatas.SubTypeID")
                                        .Terms(AISusDataArray)
                                    )
                                )
                            );
                        }
                    )))
                );
            }
        ))
    )));

在这里,我们使用了Nested查询来指定要查询的嵌套字段为AiSusDatas。然后,在Nested查询内部,我们使用Terms查询来检查AiSusData的SubTypeID是否在给定的数组AISusDataArray中。

这里假定AISusDataArray是一个包含要匹配的SubTypeID值的数组。这将返回包含匹配子查询的文档。根据您的需要,您可能需要根据查询结果来进一步处理或筛选文档。

【以下回答由 GPT 生成】

对于Elasticsearch中的嵌套多重匹配查询,可以使用bool查询和nested查询来实现。

以下是一个示例的C#代码,演示了如何使用嵌套多重匹配查询:

using Nest;

// 创建Elasticsearch客户端
var settings = new ConnectionSettings(new Uri("http://localhost:9200"));
var client = new ElasticClient(settings);

// 创建查询条件
var query = new BoolQuery
{
    Must = new List<QueryContainer>
    {
        // 匹配字段 PRN
        new MatchQuery { Field = "PRN", Query = "要匹配的PRN值" },

        // 匹配字段 ImageMode
        new MatchQuery { Field = "ImageMode", Query = "要匹配的ImageMode值" },

        // 嵌套查询 Judges 列表
        new NestedQuery
        {
            Path = "Judges",
            Query = new BoolQuery
            {
                Must = new List<QueryContainer>
                {
                    // 嵌套查询 JudgeConclusion 字段
                    new NestedQuery
                    {
                        Path = "Judges.JudgeConclusion",
                        Query = new BoolQuery
                        {
                            Must = new List<QueryContainer>
                            {
                                // 匹配 JudgeConclusion 字段的某个值
                                new MatchQuery { Field = "Judges.JudgeConclusion.FieldName1", Query = "要匹配的值" },
                                new MatchQuery { Field = "Judges.JudgeConclusion.FieldName2", Query = "要匹配的值" },
                            }
                        }
                    }
                }
            }
        },

        // 嵌套查询 Checks 列表
        new NestedQuery
        {
            Path = "Checks",
            Query = new BoolQuery
            {
                Must = new List<QueryContainer>
                {
                    // 嵌套查询 CheckConclusion 字段
                    new NestedQuery
                    {
                        Path = "Checks.CheckConclusion",
                        Query = new BoolQuery
                        {
                            Must = new List<QueryContainer>
                            {
                                // 匹配 CheckConclusion 字段的某个值
                                new MatchQuery { Field = "Checks.CheckConclusion.FieldName1", Query = "要匹配的值" },
                                new MatchQuery { Field = "Checks.CheckConclusion.FieldName2", Query = "要匹配的值" },
                            }
                        }
                    }
                }
            }
        },

        // 嵌套查询 AiSusDatas 列表
        new NestedQuery
        {
            Path = "AiSusDatas",
            Query = new BoolQuery
            {
                Must = new List<QueryContainer>
                {
                    // 嵌套查询 AiSusData 字段
                    new NestedQuery
                    {
                        Path = "AiSusDatas.AiSusData",
                        Query = new BoolQuery
                        {
                            Must = new List<QueryContainer>
                            {
                                // 匹配 AiSusData 字段的某个值
                                new MatchQuery { Field = "AiSusDatas.AiSusData.FieldName1", Query = "要匹配的值" },
                                new MatchQuery { Field = "AiSusDatas.AiSusData.FieldName2", Query = "要匹配的值" },
                            }
                        }
                    }
                }
            }
        }
    }
};

// 执行查询
var searchRequest = new SearchRequest<YourDocumentType>
{
    Query = query
};

var searchResponse = client.Search<YourDocumentType>(searchRequest);

注意事项: - 请根据你的实际情况修改代码中的参数和字段名称。 - 代码示例中的YourDocumentType是你的实体类类型,需要根据你的实际情况进行调整。 - 示例中使用的是bool查询和nested查询,你还可以根据实际需求选择其他查询类型。 - 你可以根据自己的需求添加或修改嵌套查询的逻辑。

希望以上代码能帮助到你。如果你有任何问题,请随时提问。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
根据您提供的代码和要求,如果您想在Elasticsearch中执行嵌套多重匹配查询,特别是在AiSusDatas字段的SubTypeID上执行类似SQL中的IN查询,您可以使用Terms查询条件来实现。
以下是您的代码示例中AiSusDatas字段的筛选部分更新后的代码:

return h.Nested(n => n.Path(j => j.AiSusDatas).Query(p => p.Bool(k => k.Must(
    q => q.Terms(t => t.Field("AiSusDatas.SubTypeID").Terms(AISusDataArray))
)))));

在这个示例中,我们使用Nested查询来指定要进行嵌套查询的字段路径。然后,在Query方法中,使用Bool查询来组合多个查询条件。在Bool查询的Must方法中,我们使用Terms查询来匹配AiSusDatas.SubTypeID字段与给定的AISusDataArray值数组。

请注意,Field方法中的字段名是字符串,因此我们使用"AiSusDatas.SubTypeID"作为字段名进行匹配。
根据您的具体需求和数据结构,您可能需要调整字段名和查询条件。请确保字段名和查询条件与您的实际数据和映射匹配。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

题主,这个问题我来替你解决(参考结合AI智能、文心一言),若有帮助,还望采纳,点击回答右侧采纳即可。


在Elasticsearch中,嵌套查询可以通过使用嵌套对象来实现。可以使用嵌套查询来进行多层匹配。下面是一个嵌套多重匹配查询的C#代码示例:

using Nest;

var client = new ElasticClient();
var response = client.Search<MyDocument>(s => s
    .Query(q => q
        .Nested(n => n
            .Path(p => p.InnerObject)
            .Query(nq => nq
                .Bool(b => b
                    .Must(mu => mu
                        .Match(m => m
                            .Field(f => f.InnerObject.Name)
                            .Query("value")
                        ),
                        mu => mu
                        .Match(m => m
                            .Field(f => f.InnerObject.City)
                            .Query("value")
                        )
                    )
                )
            )
        )
    )
);

在上面的代码中,我们使用了Elasticsearch的Nest客户端。我们首先创建了一个Elasticsearch客户端对象。然后,我们使用Search方法构建一个查询。在查询中,我们使用了Nested方法创建一个嵌套查询对象。该查询对象包含了Path方法指定的内部对象路径。在内部查询中,我们使用了Bool方法构建一个布尔查询对象,该对象可包含多个匹配查询。在上面的示例中,我们使用了两个Match查询,分别匹配InnerObject对象的Name和City属性。注意,多个匹配查询可以使用Must或Should方法进行逻辑运算。

上面的代码仅作为示例,实际情况中,我们需要将MyDocument替换为自己定义的文档类型,并根据需要更改查询中的属性名和匹配条件。

Elastic Search 支持嵌套查询,可以对一个字段进行多重匹配查询。以下是一个C#代码示例:

var query = new BoolQuery()
{
    Should = new List<QueryContainer>()
};
query.Should.Add(new TermQuery()
{
    Field = "category",
    Term = "books"
});
query.Should.Add(new TermQuery()
{
    Field = "category",
    Term = "electronics"
});

var searchRequest = new SearchRequest("my_index", "my_type")
{
    Query = query
};
var searchResponse = client.Search(searchRequest);

在上面的示例中,我们使用了 BoolQuery 来构建多重匹配查询。我们将两个 TermQuery 添加到 Should 列表中,表示我们希望文档同时包含 "books" 和 "electronics" 两个类别。最后,我们将查询对象传递给 SearchRequest,并执行搜索操作。

需要注意的是,嵌套查询只能在 BoolQuery 中使用,并且 Should 列表中的查询必须返回 true 或 false,不能返回另一个 BoolQuery。如果需要进行更复杂的多重匹配查询,可以使用 BoolQuery 的 Must、Filter、MustNot 等子句来组合多个查询。

结合GPT给出回答如下请题主参考
对于Elastic Search的嵌套多重匹配查询,您可以使用嵌套查询(nested query)和布尔查询(bool query)实现。

嵌套查询可以在一个父级文档中查询包含多个子文档的字段。假设您的实体类中有一个嵌套字段nestedField,您可以使用以下代码进行查询:

var response = client.Search<MyClass>(s => s
    .Query(q => q
        .Nested(n => n
            .Path(p => p.nestedField)
            .Query(qq => qq
                .Bool(b => b
                    .Must(m => m
                        .Match(ma => ma
                            .Field(f => f.nestedField.First().NestedField1)
                            .Query("value1")
                        ),
                        m => m
                        .Match(ma => ma
                            .Field(f => f.nestedField.First().NestedField2)
                            .Query("value2")
                        )
                    )
                )
            )
        )
    )
);

上面的代码中,我们首先声明了一个嵌套查询,指定了嵌套字段的路径,然后在子查询中使用了布尔查询实现多重匹配。在布尔查询中,我们定义了两个匹配条件,分别针对nestedField中的NestedField1和NestedField2字段。

对于多值查询,您可以使用terms查询来匹配包含多个值的字段。假设您的实体类中有一个字段multiField,您可以使用以下代码进行多值查询:

var response = client.Search<MyClass>(s => s
    .Query(q => q
        .Terms(t => t
            .Field(f => f.multiField)
            .Terms("value1", "value2", "value3")
        )
    )
);

上面的代码中,我们使用了terms查询,指定了multiField字段匹配的多个值。这样可以同时匹配包含任何一个值的文档。

援引讯飞星火:
在最后的 AiSusDatas 筛选中,你可以使用 Terms 查询来匹配 SubTypeID 在给定数组中的文档。你已经正确地使用了 Terms 查询,但是需要确保 AISusDataArray 是一个有效的数组。以下是一个示例:

var AISusDataArray = new[] { 1, 2, 3 }; // 用你需要的 SubTypeID 替换这些数字

var response = ESClient.Search<CustomCTImageInfo>(s => s.From((request.CurrentPage - 1)* request.PageSize).Size(request.PageSize)
               .Sort(i => i.Descending(f => f.CreateTime))
               .TrackTotalHits()
               .Query(query: q => q.Bool(m => m.Must(
                  
                   fs => fs.Bool(sh=>sh.Should(
                     
                        f =>
                        {
                            return f.Nested(
                                l => l.Path(j => j.AiSusDatas).Query(p => p.Bool(k => k.Must(
                                    h =>
                                    {
                                        if (string.IsNullOrEmpty(request.AISusDataId.ToString()) ||
                                            request.AISusDataId.ToString().Equals("-1"))
                                        {
                                            return new QueryContainer();
                                        }

                                        return h.Terms(o =>
                                                o.Field(n => n.AiSusDatas.First().SubTypeID)
                                                    .Terms(AISusDataArray));
                                    }
                                )))
                            );
                        }
                       ))
               ));

这段代码将会返回所有 SubTypeID 在 AISusDataArray 中的 AiSusData 文档。如果 AISusDataArray 为空或者没有匹配的文档,查询结果将为空。

根据您提供的代码,您想要查询AiSusData中的SubTypeID是否存在于给定的数组AISusDataArray中。要实现这个查询,您可以使用Terms查询。以下是您可以更改的查询部分的示例代码:

return h.Nested(n => n.Path(j => j.AiSusDatas).Query(q => q.Terms(t => t.Field("aiSusDatas.subTypeID").Terms(AISusDataArray))));

在这个示例中,我们使用了Nested查询来指定嵌套路径为AiSusDatas,然后在Query中使用了Terms查询来匹配SubTypeID字段是否存在于给定的数组AISusDataArray中。

请注意,这里的aiSusDatas.subTypeID是使用了字符串表示嵌套路径和字段名,您可能需要根据实际情况进行调整。

参考gpt:
结合自己分析给你如下建议:
您可以使用nested query和terms query来实现您的需求。nested query可以让您搜索嵌套的对象,就像它们是单独的文档一样。terms query可以
让您搜索一个字段中包含一个或多个精确值的文档。您的代码中,您已经使用了nested query来指定要搜索的路径(AiSusDatas),然后使用了terms query来指定要匹配的字段(SubTypeID)和值(AISusDataArray)。这样就可以实现AiSusData中的SubTypeID在数组中的查询。

您的代码看起来是正确的,只是有一点小问题。您在terms query中使用了First()方法来指定要搜索的字段,这可能会导致只搜索第一个嵌套对象中的SubTypeID,而不是所有嵌套对象中的SubTypeID。为了避免这个问题,您应该使用Suffix()方法来添加一个通配符(*)到字段名,这样就可以匹配所有嵌套对象中的SubTypeID。例如:

return h.Terms(o => o.Field(n => n.AiSusDatas.Suffix(“*.SubTypeID”)) .Terms(AISusDataArray));

试试

var AISusDataArray = new int[] {1, 2, 3}; 
var response = ESClient.Search<CustomCTImageInfo>(s => s.From((request.CurrentPage - 1)* request.PageSize).Size(request.PageSize)
               .Sort(i => i.Descending(f => f.CreateTime))
               .TrackTotalHits()
               .Query(query: q => q.Bool(m => m.Must(
                  
                   fs => fs.Bool(sh=>sh.Should(
                     
                        f =>
                        {
                            return f.Nested(
                                l => l.Path(j => j.AiSusDatas).Query(p => p.Bool(k => k.Must(
                                    h =>
                                    {
                                        if (string.IsNullOrEmpty(request.AISusDataId.ToString()) ||
                                            request.AISusDataId.ToString().Equals("-1"))
                                        {
                                            return new QueryContainer();
                                        }
                                        return h.Terms(o =>
                                          o.Field(n => n.AiSusDatas.First().SubTypeID)
                                              .Terms(AISusDataArray));
                                    }
                                ))).InnerHits() 
                            );
                        }
                       ))


你可以使用.Terms方法来查询嵌套字段的数组。在你的情况下,你想查询AiSusDatas数组中的SubTypeID字段,以确保它们在给定的AISusDataArray中。
调整你的查询

return h.Terms(t => t
    .Field(f => f.AiSusDatas[0].SubTypeID) // 注意这里是使用[0]来引用嵌套数组中的第一个元素的SubTypeID字段
    .Terms(AISusDataArray)
);


在上面的代码中,我们使用了.AiSusDatas[0].SubTypeID来引用嵌套数组中的第一个元素的SubTypeID字段。这是因为你的数据模型中,AiSusDatas是一个List,所以你需要指定数组中的元素,然后再引用其字段。

这个查询将查找AiSusDatas数组中的第一个元素的SubTypeID字段是否包含在AISusDataArray中。

Elasticsearch-----nested查询 多重聚合与嵌套

用 Terms 查询来实现类似于 SQL 中的 IN 查询

可以使用Elasticsearch的C#客户端库。下面是一个示例代码,展示了如何使用C#编写查询来匹配具有特定AiSusData.SubTypeID的CustomCTImageInfo文档。

csharp
using Elasticsearch.Net;
using Elasticsearch.Net.Queries;
using Elasticsearch.Net.Search;

// 假设 ESClient 是一个已经初始化的 ElasticsearchClient 实例

var searchRequest = new SearchRequest<CustomCTImageInfo>()
    .From((request.CurrentPage - 1) * request.PageSize)
    .Size(request.PageSize)
    .Sort(i => i.Descending(f => f.CreateTime))
    .TrackTotalHits()
    .Query(query => query.Bool(m => m.Must(
        fs => fs.Bool(sh => sh.Should(
            f => f.Nested(
                l => l.Path(j => j.AiSusDatas).Query(ai => ai.Terms(t => t.Field(f => f.AiSusDatas.SubTypeID).Terms("value1", "value2")))
            ))
        )));

var response = ESClient.Search<CustomCTImageInfo>(searchRequest);

参考gpt
在Elasticsearch中进行多值查询可以使用Terms查询来实现。以下是一个示例代码,演示如何在C#中使用嵌套多重匹配查询:

var subTypeIds = new List<int> { 1, 2, 3 }; // 假设要查询的SubTypeID数组

var response = ESClient.Search<CustomCTImageInfo>(s => s
    .From((request.CurrentPage - 1) * request.PageSize)
    .Size(request.PageSize)
    .Sort(i => i.Descending(f => f.CreateTime))
    .TrackTotalHits()
    .Query(query: q => q.Bool(m => m.Must(
        fs => fs.Bool(sh => sh.Should(
            f => f.Nested(n => n
                .Path(p => p.AiSusDatas)
                .Query(qq => qq.Terms(t => t
                    .Field(ff => ff.AiSusDatas.First().SubTypeID)
                    .Terms(subTypeIds)
                ))
            )
        ))
    )))
);

在上述代码中,我们创建了一个SubTypeID数组 subTypeIds,然后在查询中使用了Terms查询来匹配AiSusData中的SubTypeID字段。通过Nested查询来指定路径为AiSusDatas,然后使用Terms查询来匹配SubTypeID字段,并传入SubTypeID数组作为查询条件。

请确保您已经正确设置了Elasticsearch的连接和索引,并将上述代码中的ESClient替换为您的Elasticsearch客户端实例。

BoolQuery可以查询

使用布尔查询(Bool Query)结合嵌套查询(Nested Query)来实现