Elasticsearch通过查询其他文档对对象进行聚合

时间:2016-12-10 06:09:01

标签: elasticsearch nest

假设我有一个索引,其中包含代表讨论中消息的文档 该文档拥有discussionId属性。 (它也有自己的ID"代表MessageId")

现在,我需要找到所有没有与查询匹配的文档(消息)的discussionIds 例如:
"查找所有没有包含文字消息的discussionIds' YO YO'"

我该怎么做?

这个类与此类似:

  public class Message
  {
     public string Id{get;set}
     public string DiscussionId {get;set}
     public string Text{get;set}
  }

1 个答案:

答案 0 :(得分:1)

您只需要在matches for the phrase中找到可以找到bool query must_not clause“YO YO”的查询。

使用NEST

client.Search<Message>(s => s
    .Query(q => q
        .Bool(b => b
            .MustNot(mn => mn
                .MatchPhrase(m => m
                    .Field(f => f.Text)
                    .Query("YO YO")
                )
            )
        )
    )
);

operator overloading,可以缩短为

client.Search<Message>(s => s
    .Query(q => !q
        .MatchPhrase(m => m
            .Field(f => f.Text)
            .Query("YO YO")
        )
    )
);

两者都产生查询

{
  "query": {
    "bool": {
      "must_not": [
        {
          "match": {
            "text": {
              "type": "phrase",
              "query": "YO YO"
            }
          }
        }
      ]
    }
  }
}

要仅返回DiscussionId值,您可以使用source filtering

client.Search<Message>(s => s
    .Source(sf => sf
        .Includes(f => f
            .Field(ff => ff.DiscussionId)
        )
    )
    .Query(q => !q
        .MatchPhrase(m => m
            .Field(f => f.Text)
            .Query("YO YO")
        )
    )
);

而且,如果你想要全部获得它们,你可以使用scroll API

var searchResponse = client.Search<Message>(s => s
    .Scroll("1m")
    .Source(sf => sf
        .Includes(f => f
            .Field(ff => ff.DiscussionId)
        )
    )
    .Query(q => !q
        .MatchPhrase(m => m
            .Field(f => f.Text)
            .Query("YO YO")
        )
    )
);

// fetch the next batch of documents, using the scroll id returned from
// the previous call. Do this in a loop until no more docs are returned.
searchResponse = client.Scroll<Message>("1m", searchResponse.ScrollId);