我在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": []
}
},
...
通过使用C#Nest API,我想获取具有空配置文件的postmodel(上面示例数据中的第二篇文章)。我已经尝试了许多方法来编写正确的查询,但是我在下面用此查询结束了,但仍然不能给我正确的结果。我当前的代码如下所示:
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;
}));
如果有人可以帮助我解决这个问题,我将非常高兴。先感谢您。
最佳答案
这是一个完整的示例,说明如何通过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; }
}
这仅返回一个带有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" : [ ]
}
}
]
}
}
通过对查询使用operator overloading,查询可以更简洁地表达
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)
)
)
)
)
);
关于c# - 带C#嵌套客户端的elasticsearch空数组搜索查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48113747/