简体   繁体   English

带C#嵌套客户端的elasticsearch空数组搜索查询

[英]elasticsearch empty array search query with c# nest client

I have a model in elasticsearch like this: 我在Elasticsearch中有一个这样的模型:

"hits": [
{
  "_index": "post",
  "_type": "postmodel",
  "_source": {
    "projectId": "2",
    "language": "en",
    "postDate": "2017-06-11T08:39:32Z",
    "profiles": [
      {
        "label": "Emotional",
        "confidence": 1
      }
    ]
  }
},
{
  "_index": "post",
  "_type": "postmodel",
  "_source": {
    "projectId": "3",
    "language": "en",
    "postDate": "2017-06-11T08:05:01Z",
    "profiles": []
  }
},
...

By using c# Nest API, i want to fetch the postmodels that has empty profiles (the second post in the example data above). 通过使用c#Nest API,我想获取具有空配置文件的postmodel(上面示例数据中的第二篇文章)。 I have tried many ways to write the right query but i've ended up with this query below and still it doesnt give me the right results. 我已经尝试了许多方法来编写正确的查询,但是我在下面用此查询结束了,但它仍然没有给我正确的结果。 My current code looks like this: 我当前的代码如下所示:

var postModels = await _elasticClient.SearchAsync<PostModel>(s => s
        .Index("post")
        .Query(q =>
        {
            QueryContainer query = new QueryContainer();

            query = query && q.Match(m => m.Field(f => f.ProjectId)
            .Query("3"));

            query = query && q.Nested(n => n.Path(p => p.Profiles)
                        .Query(qn => qn.Bool(b => b.Must(bm => bm.Match(m => m
                        .Field(f => f.Profiles).Query(null))))));

            return query;
        }));

I would be happy if someone can help me with this problem. 如果有人可以帮助我解决这个问题,我将非常高兴。 Thank you in advance. 先感谢您。

Here's a complete example of how you can accomplish it with an exists query in a must_not clause 这是一个完整的示例,说明如何使用must_not子句中的exists查询来完成此must_not

private static void Main()
{
    var defaultIndex = "post";

    var settings = new ConnectionSettings(new Uri("http://localhost:9200"))
        .DefaultIndex(defaultIndex);

    var client = new ElasticClient(settings);

    if (client.IndexExists(defaultIndex).Exists)
        client.DeleteIndex(defaultIndex);

    client.CreateIndex(defaultIndex, c => c
        .Settings(s => s
            .NumberOfShards(1)
            .NumberOfReplicas(0)
        )
        .Mappings(m => m
            .Map<PostModel>(mm => mm
                .AutoMap()
                .Properties(p => p
                    .Nested<Profile>(np => np
                        .Name(n => n.Profiles)
                        .AutoMap()
                    )
                )
            )
        )
    );

    var posts = new List<PostModel>
    {
        new PostModel
        {
            ProjectId = "2",
            Language = "en",
            PostDate = new DateTime(2017, 6, 11, 8, 39, 32, DateTimeKind.Utc),
            Profiles = new List<Profile>
            {
                new Profile
                {
                    Label = "Emotional",
                    Confidence = 1
                }
            }
        },
        new PostModel
        {
            ProjectId = "3",
            Language = "en",
            PostDate = new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc),
            Profiles = new List<Profile>
            {
                new Profile
                {
                    Label = "Lazy",
                    Confidence = 3
                }
            }
        },
        new PostModel
        {
            ProjectId = "3",
            Language = "en",
            PostDate = new DateTime(2017, 6, 11, 8, 5, 1, DateTimeKind.Utc),
            Profiles = new List<Profile>()
        }
    };

    client.IndexMany(posts);
    client.Refresh(defaultIndex);

    var postModels = client.Search<PostModel>(s => s
        .Query(q =>
        {
            QueryContainer query = q
                .Match(m => m
                    .Field(f => f.ProjectId)
                    .Query("3")
                );

            query = query && q
                .Bool(b => b
                    .MustNot(bm => bm
                        .Nested(n => n
                            .Path(p => p.Profiles)
                            .Query(qn => qn
                                .Exists(m => m
                                    .Field(f => f.Profiles)
                                )
                            )
                        )               
                    )           
            );

            return query;
        }));
}

public class Profile 
{
    public string Label { get; set; }

    public int Confidence { get; set; }

}

public class PostModel
{
    public string ProjectId { get; set; }

    public string Language { get; set; }

    public DateTime PostDate { get; set; }

    public List<Profile> Profiles { get; set; }
}

This returns just the one document with projectId 3 and no profiles 这仅返回一个带有projectId 3且没有配置文件的文档

{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.47000363,
    "hits" : [
      {
        "_index" : "post",
        "_type" : "postmodel",
        "_id" : "qeNF72ABeLoaZkUgC2Xh",
        "_score" : 0.47000363,
        "_source" : {
          "projectId" : "3",
          "language" : "en",
          "postDate" : "2017-06-11T08:05:01Z",
          "profiles" : [ ]
        }
      }
    ]
  }
}

With operator overloading on queries, the query can be expressed more succinctly 通过运算符对查询的重载 ,查询可以更简洁地表示

var postModels = client.Search<PostModel>(s => s
    .Query(q => q
        .Match(m => m
            .Field(f => f.ProjectId)
            .Query("3")
        ) && !q
        .Nested(n => n
            .Path(p => p.Profiles)
            .Query(qn => qn
                .Exists(m => m
                    .Field(f => f.Profiles)
                )
            )
        )               
    )
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM