2017-09-26 7 views
1

Je suis en train d'accomplir ce qui se résume à une AND booléenne sur des documents imbriqués dans ElasticSearch. Disons que j'ai les deux documents suivants.correspondent aux propriétés multiples sur le même document imbriqué dans ElasticSearch

{ 
    "id": 1, 
    "secondLevels": [ 
     { 
      "thirdLevels": [ 
       { 
        "isActive": true, 
        "user": "[email protected]" 
       } 
      ] 
     }, 
     { 
      "thirdLevels": [ 
       { 
        "isActive": false, 
        "user": "[email protected]" 
       } 
      ] 
     } 
    ] 
} 
{ 
    "id": 2, 
    "secondLevels": [ 
     { 
      "thirdLevels": [ 
       { 
        "isActive": true, 
        "user": "[email protected]" 
       } 
      ] 
     } 
    ] 
} 

Dans ce cas, je veux correspondre uniquement les documents (dans ce cas ID: 2) qui ont un document imbriqué avec les deux isActive: true ET user: [email protected].

{ 
    "query": { 
     "bool": { 
      "must": [ 
       { 
        "nested": { 
         "path": "secondLevels.thirdLevels", 
         "query": { 
          "bool": { 
           "must": [ 
            { 
             "term": { 
              "secondLevels.thirdLevels.isActive": true 
             } 
            }, 
            { 
             "term": { 
              "secondLevels.thirdLevels.user": "[email protected]" 
             } 
            } 
           ] 
          } 
         } 
        } 
       } 
      ] 
     } 
    } 
} 

Cependant, ce qui semble se produire est que ma requête se présente deux documents parce que le premier document a un thirdLevel qui a isActive: true et un autre thirdLevel qui a l'utilisateur approprié.

Est-il possible d'appliquer cette stricte au moment de la requête/filtre ou dois-je faire cela dans un script?

+0

Quelle version de l'élastique utilisez-vous? J'ai créé un index et testé votre requête localement et je retourne seulement à l'utilisateur id = 2. La raison pour laquelle je demande, je crois que le « doit » groupement devrait être en défaut à et à moins que vous en défaut peut-être en quelque sorte à OU – Miek

Répondre

2

Avec emboîtés-objets et-requête imbriquée, vous avez fait la plupart du temps.

Tout ce que vous avez à faire est maintenant d'ajouter le drapeau inner hits et également utiliser source filtering pour des documents entiers de déplacement secondLevels sur le chemin:

{ 
    "query": { 
    "bool": { 
     "must": [ 
     { 
      "nested": { 
      "path": "secondLevels.thirdLevels", 
      "query": { 
       "bool": { 
       "must": [ 
        { 
        "term": { 
         "secondLevels.thirdLevels.isActive": true 
        } 
        }, 
        { 
        "term": { 
         "secondLevels.thirdLevels.user": "[email protected]" 
        } 
        } 
       ] 
       } 
      }, 
      "inner_hits": { 
       "size": 100 
      } 
      } 
     } 
     ] 
    } 
    } 
}