查询文档并过滤嵌套字符串列表中的特定值(即标记)

时间:2015-04-05 11:43:05

标签: c# elasticsearch nest

我对NEST及其查询有一些问题&过滤关于相对简单的文档结构的语法。

给定文档类型'BlogPosts',如下所示:

public class BlogPosts
{
    public Guid Id { get; set; }
    public Guid UserId { get; set; }
    public DateTime CreatedAt { get; set; }
    public string Content { get; set; }

    public List<string> Tags { get; set; }
    public List<Guid> ReferencedUserIds { get; set; }
}

我可以将实例发送到我的ES实例并将它们编入索引就好了,即发送/索引的json看起来像这样:

 {
  "id": "ad61de92-c6f6-49c1-84eb-0a4dfdf86cc0",
  "userId": "c43e1be7-0b8c-4271-bf29-7434719fbcbf",
  "createdAt": "2015-04-05T11:23:58.1017261Z",
  "content": "Some Specific Word in here",
  "tags": [
    "Some",
    "Tag",
    "SomeSpecialTag"
  ],
  "referencedUserIds": [
    "f6a714a0-318d-49d7-9940-f0480c002577",
    "e582c24c-1c82-43f8-8e80-09e19749a0a3",
    "11165e0b-8e4f-466a-8c37-e0cfec81850c"
  ]
}

现在使用NEST我可以轻松查询所有带有'SomeSpecialTag'标签的BlogPosts:

var postsQueriedForSpecialTag = elasticClient.Search<BlogPosts>(postSearch => postSearch
                .Index(indexName)
                .Query(
                    queryDescriptor => queryDescriptor.Match(match => match.OnField(posts => posts.Tags).Query("SpecialTag"))));

..但我真正想要的是

a)查询 了解具体内容和

b)过滤 基于特定标记(以及可选的特定UserId)

但是这会返回0个文件:

var postsFilteredForSpecialTag = elasticClient.Search<BlogPosts>(postSearch => postSearch
    .Index(indexName)
    .Query(
        queryDescriptor => queryDescriptor.QueryString(q => q.Query("Some Specific Word")))
        .Filter(descriptor => descriptor.Nested(filterDescriptor => filterDescriptor.Path(posts => posts.Tags).Filter(descriptor1 => descriptor1.Term(posts => posts.Tags, "SpecialTag")))));

..我想知道为什么。或者更确切地说,如上所述,在嵌套List<string or Guid>结构上过滤的正确NEST语法是什么?

*更新:

遵循Jettro的提示并使用'应用'过滤器(参见https://stackoverflow.com/a/28001971/2591),它现在可以完美地运行。最终的查询+过滤器代码现在看起来像这样:

var postsFilteredForSpecialTag = elasticClient.Search<BlogPosts>(postSearch => postSearch
                .Index(indexName)
                .Query(
                    queryDescriptor => queryDescriptor.QueryString(q => q.Query("Some Specific Word")))
                    .Filter(descriptor => descriptor.Bool(filterDescriptor => filterDescriptor.Should(descriptor1 => descriptor1.Term(posts => posts.Tags, "specialtag")))));

1 个答案:

答案 0 :(得分:0)

这可能是您的映射中的问题。虽然我不是NEST专家,但它可能是一个普遍的问题。可以是默认的Filter是Term过滤器吗?如果未指定标记字段的映射,则它是标准分析器。使用该分析器,可删除大写字符。执行查询将产生相同的效果,但不会分析术语过滤器,因此将找不到使用Capitals“SpecialTag”的术语。将其更改为“特殊标记”,然后重试或在映射中使字段not_analyzed。