1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
 * Copyright 2016-2018 Ben Ashford
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//! Joining queries

use serde::Serialize;

use crate::json::ShouldSkip;

use super::{Query, ScoreMode};

/// Nested query
#[derive(Debug, Default, Serialize)]
pub struct NestedQuery {
    path: String,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    score_mode: Option<ScoreMode>,
    query: Query,
}

impl Query {
    pub fn build_nested<A, B>(path: A, query: B) -> NestedQuery
    where
        A: Into<String>,
        B: Into<Query>,
    {
        NestedQuery {
            path: path.into(),
            query: query.into(),
            ..Default::default()
        }
    }
}

impl NestedQuery {
    add_field!(with_score_mode, score_mode, ScoreMode);

    build!(Nested);
}

/// Has Child query
#[derive(Debug, Default, Serialize)]
pub struct HasChildQuery {
    doc_type: String,
    query: Query,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    score_mode: Option<ScoreMode>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    min_children: Option<u64>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    max_children: Option<u64>,
}

/// Has Parent query
#[derive(Debug, Default, Serialize)]
pub struct HasParentQuery {
    parent_type: String,
    query: Query,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    score_mode: Option<ScoreMode>,
}

impl Query {
    pub fn build_has_child<A, B>(doc_type: A, query: B) -> HasChildQuery
    where
        A: Into<String>,
        B: Into<Query>,
    {
        HasChildQuery {
            doc_type: doc_type.into(),
            query: query.into(),
            ..Default::default()
        }
    }

    pub fn build_has_parent<A, B>(parent_type: A, query: B) -> HasParentQuery
    where
        A: Into<String>,
        B: Into<Query>,
    {
        HasParentQuery {
            parent_type: parent_type.into(),
            query: query.into(),
            ..Default::default()
        }
    }
}

impl HasChildQuery {
    add_field!(with_score_mode, score_mode, ScoreMode);
    add_field!(with_min_children, min_children, u64);
    add_field!(with_max_children, max_children, u64);

    build!(HasChild);
}

impl HasParentQuery {
    add_field!(with_score_mode, score_mode, ScoreMode);

    build!(HasParent);
}