2015-05-06 3 views
2

Предположим, что у нас есть вложенный комментарий объекта с двумя тегами свойств и группой. Если я делаю ниже запроса, это дает мне желаемый результат.Свойства вложенных объектов запроса в отношении нескольких значений в elasticsearch

{ 
 
    "query": { 
 
    "bool": { 
 
     "must": { 
 
     "nested": { 
 
      "query": { 
 
      "bool": { 
 
       "must": { 
 
       "match": { 
 
        "comment.tag": { 
 
        "query": "SPRING", 
 
        "type": "boolean" 
 
        } 
 
       } 
 
       }, 
 
       "must_not": { 
 
       "match": { 
 
        "comment.group": { 
 
        "query": "ABC", 
 
        "type": "boolean" 
 
        } 
 
       } 
 
       } 
 
      } 
 
      }, 
 
      "path": "comment" 
 
     } 
 
     } 
 
    } 
 
    } 
 
}

Но если выполнить ниже запрос, то это не дает мне желаемого результата.

{ 
 
    "query": { 
 
    "bool": { 
 
     "must": { 
 
     "nested": { 
 
      "query": { 
 
      "bool": { 
 
       "must": { 
 
       "match": { 
 
        "comment.tag": { 
 
        "query": [ 
 
         "SPRING", 
 
         "HIBERNATE" 
 
        ], 
 
        "type": "boolean" 
 
        } 
 
       } 
 
       }, 
 
       "must_not": { 
 
       "match": { 
 
        "comment.group": { 
 
        "query": [ 
 
         "ABC", 
 
         "XYZ" 
 
        ], 
 
        "type": "boolean" 
 
        } 
 
       } 
 
       } 
 
      } 
 
      }, 
 
      "path": "comment" 
 
     } 
 
     } 
 
    } 
 
    } 
 
}

Разница между этими двумя, что я запрашивая оба свойства вложенного объекта с несколькими значениями.

Со вторым запросом он просто берет последние значения в списке, предоставленном для поиска и возвращает результат.

Есть ли способ написать запрос, где я могу указать список перечней значений, и все значения включены в поиск?

ответ

2

Это не имеет никакого отношения к вложенному запросу/фильтру. Вместо этого вы используете match query. Он не ожидает массив значений.

Есть два способа добиться того, что вы пытаетесь. Прежде чем идти в них, я хотел бы отметить, что запрос match по умолчанию использует тип boolean, поэтому вы можете оставить это.

  1. Вы можете изменить запрос match, чтобы просто указать оба значения в строке. Порядок не имеет значения:

    "bool" : { 
        "must" : { 
        "match" : { 
         "comment.tag" : "SPRING HIBERNATE" 
        } 
        } 
    } 
    

    Причина, по которой это работает, потому что поле будет использовать анализатор поиска разметить строку таким же образом, что поле индексируются (по умолчанию). В результате, предположив стандартный анализатор строк, вы в конечном итоге найдете springилиhibernate. Поскольку вы не используете выражение фразы, заказ действительно неактуальен.

  2. Другой способ заключается в явном виде отделить их, используя внешний bool/must запрос (то же относится и к must_not и should). Так как вы хотите, чтобы они относились как OR с, вам нужно использовать should вместо must таким образом:

    "bool" : { 
        "should" : [ 
        { 
         "match" : { "company.tag" : "SPRING" } 
        }, 
        { 
         "match" : { "company.tag" : "HIBERNATE" } 
        } 
        ] 
    } 
    

    Примечание: Если вы также включать в себя must, то вам необходимо установить minimum_should_match в 1 (внутри bool объекта), чтобы он не стал необязательным. Без must и must_not, это неявно 1.

+0

Первое решение делает работу, но второй один не работал. Спасибо за вашу помощь по этому поводу. –

+0

О, woops. Второй должен быть 'должен' вместо' must', чтобы он обрабатывался как 'или' вместо' and'. – pickypg

Смежные вопросы