nested检索, 父子查询

过滤nested文档

6.1前 _type 不是以 "__"开头的。

6.1之后根据是否存在_primary_term属性

org.elasticsearch.index.query.NestedQueryBuilder doToQuery


    /**
     * Creates a new non-nested docs query
     * @param indexVersionCreated the index version created since newer indices can identify a parent field more efficiently
     */
    public static Query newNonNestedFilter(Version indexVersionCreated) {
        if (indexVersionCreated.onOrAfter(Version.V_6_1_0)) {
            return new DocValuesFieldExistsQuery(SeqNoFieldMapper.PRIMARY_TERM_NAME);
        } else {
            return new BooleanQuery.Builder()
                .add(new MatchAllDocsQuery(), Occur.FILTER)
                .add(newNestedFilter(), Occur.MUST_NOT)
                .build();
        }
    }

最终会调用Lucene的ToParentBlockJoinQuery来完成查找。 

    public ESToParentBlockJoinQuery(Query childQuery, BitSetProducer parentsFilter, ScoreMode scoreMode, String path) {
        this(new ToParentBlockJoinQuery(childQuery, parentsFilter, scoreMode), path, scoreMode);
    }

父子查询

public abstract class JoinQueryBuilders {
    /**
     * Constructs a new has_child query, with the child type and the query to run on the child documents. The
     * results of this query are the parent docs that those child docs matched.
     *
     * @param type      The child type.
     * @param query     The query.
     * @param scoreMode How the scores from the children hits should be aggregated into the parent hit.
     */
    public static HasChildQueryBuilder hasChildQuery(String type, QueryBuilder query, ScoreMode scoreMode) {
        return new HasChildQueryBuilder(type, query, scoreMode);
    }

    /**
     * Constructs a new parent query, with the parent type and the query to run on the parent documents. The
     * results of this query are the children docs that those parent docs matched.
     *
     * @param type      The parent type.
     * @param query     The query.
     * @param score     Whether the score from the parent hit should propagate to the child hit
     */
    public static HasParentQueryBuilder hasParentQuery(String type, QueryBuilder query, boolean score) {
        return new HasParentQueryBuilder(type, query, score);
    }

    /**
     * Constructs a new parent id query that returns all child documents of the specified type that
     * point to the specified id.
     */
    public static ParentIdQueryBuilder parentId(String type, String id) {
        return new ParentIdQueryBuilder(type, id);
    }
}

最终调用了JoinUtil.createJoinQuery来完成join操作
        @Override
        public Query rewrite(IndexReader reader) throws IOException {
            Query rewritten = super.rewrite(reader);
            if (rewritten != this) {
                return rewritten;
            }
            if (reader instanceof DirectoryReader) {
                IndexSearcher indexSearcher = new IndexSearcher(reader);
                indexSearcher.setQueryCache(null);
                indexSearcher.setSimilarity(similarity);
                IndexOrdinalsFieldData indexParentChildFieldData = fieldDataJoin.loadGlobal((DirectoryReader) reader);
                OrdinalMap ordinalMap = indexParentChildFieldData.getOrdinalMap();
                // 调用JoinUtil完成join操作
                return JoinUtil.createJoinQuery(joinField, innerQuery, toQuery, indexSearcher, scoreMode,
                    ordinalMap, minChildren, maxChildren);
            } else {
                if (reader.leaves().isEmpty() && reader.numDocs() == 0) {
                    // asserting reader passes down a MultiReader during rewrite which makes this
                    // blow up since for this query to work we have to have a DirectoryReader otherwise
                    // we can't load global ordinals - for this to work we simply check if the reader has no leaves
                    // and rewrite to match nothing
                    return new MatchNoDocsQuery();
                }
                throw new IllegalStateException("can't load global ordinals for reader of type: " +
                    reader.getClass() + " must be a DirectoryReader");
            }
        }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值