elastic 对嵌套对象进行增删改查

嵌套查询

嵌套示例

es 的 mapping 中有如下嵌套 List 对象:

"properties": {
  "type": "nested",
  "properties": {
    "value": {
      "type": "text",
      "fields": {
        "keyword": {
          "ignore_above": 256,
          "type": "keyword"
        }
      }
    },
    "key": {
      "type": "keyword"
    }
  }
}

查询示例

存在查询

BoolQueryBuilder bool = QueryBuilders.boolQuery();
TermQueryBuilder termQuery = QueryBuilders.termQuery("properties.key", key);
BoolQueryBuilder filterBoolQuery = QueryBuilders.boolQuery().filter(termQuery);
bool.filter(QueryBuilders.nestedQuery("properties", filterBoolQuery, ScoreMode.None));

不存在查询

BoolQueryBuilder bool = QueryBuilders.boolQuery();
TermQueryBuilder termQuery = QueryBuilders.termQuery("properties.key", key);
BoolQueryBuilder filterBoolQuery = QueryBuilders.boolQuery().filter(termQuery);
NestedQueryBuilder nestedQuery = QueryBuilders.nestedQuery("properties", filterBoolQuery, ScoreMode.None);
bool.filter(QueryBuilders.boolQuery().mustNot(nestedQuery));

范围查询

如果你的时间戳是以毫秒为单位的长整型数字,并且被存储为字符串,你仍然可以使用 rangeQuery 进行范围查询。

只需要将你的时间范围也转换为相应的字符串格式即可。

BoolQueryBuilder bool = QueryBuilders.boolQuery();
bool.must(QueryBuilders.nestedQuery(
    "properties", // 嵌套字段的路径
    QueryBuilders.boolQuery()
        .must(QueryBuilders.termQuery("properties.key", "updatetime")) // 匹配key
        .must(QueryBuilders.rangeQuery("properties.value.keyword") // 对value进行范围查询
            .from(String.valueOf(startTimeMillis))
            .to(String.valueOf(endTimeMillis))),
    ScoreMode.None // 分数模式,这里不需要计算分数
));

模糊查询

BoolQueryBuilder bool = QueryBuilders.boolQuery();
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
        .filter(QueryBuilders.termQuery("properties.key", key))
        .filter(QueryBuilders.matchPhraseQuery("properties.value", value));
bool.filter(QueryBuilders.nestedQuery("properties", queryBuilder, ScoreMode.Total));

精确查询

BoolQueryBuilder bool = QueryBuilders.boolQuery();
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
        .filter(QueryBuilders.termQuery("properties.key", key))
        .filter(QueryBuilders.termQuery("properties.value.keyword", value));
bool.filter(QueryBuilders.nestedQuery("properties", queryBuilder, ScoreMode.Total));
Query boolQuery = Query.of(q2 -> q2.bool(b -> b
                                         .filter(f -> f.term(t -> t.field("properties.key").value(key)))
                                         .filter(f -> f.term(m -> m.field("properties.value.keyword").value(value)))
                                        ));
Query nestedQuery = Query.of(q -> q.nested(NestedQuery.of(n -> n.path("properties").query(boolQuery))));
queryList.add(nestedQuery);

精确多值查询

BoolQueryBuilder bool = QueryBuilders.boolQuery();
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
        .filter(QueryBuilders.termQuery("properties.key", key))
        .filter(QueryBuilders.termsQuery("properties.value.keyword", value.split(";;"))); // 注意用 termsQuer
bool.filter(QueryBuilders.nestedQuery("properties", queryBuilder, ScoreMode.Total));