我在弹性搜索中有一个像这样的模型:
"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,我想获取具有空配置文件的postmodels(上面示例数据中的第二篇文章)。我已经尝试了很多方法来编写正确的查询,但我最终得到了下面的查询,但它仍然没有给我正确的结果。我目前的代码如下:
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;
}));
如果有人可以帮我解决这个问题,我会很高兴。提前谢谢。
答案 0 :(得分:1)
以下是在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)
)
)
)
)
);