Неправильные результаты в сложном булевом запросеasticsearch над вложенными объектами - PullRequest
0 голосов
/ 21 мая 2018

У меня есть индекс получателей, содержащий вложенный объект действия, в котором хранятся типы событий и идентификаторы кампании.

Вот пример:

{
    email: 'm1@example.com',
    userId: 'user-id'
    listId: 'list-id'
    campaignActivity: [
       { event: 'received', campaignId: 'c1', timestamp: 1 },
       { event: 'received', campaignId: 'c3', timestamp: 3 }
    ]
}

Вот мое текущее отображение:

{
  "recipients_index_test": {
    "mappings": {
      "recipients": {
        "properties": {
          "campaignActivity": {
            "type": "nested",
            "properties": {
              "campaignId": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "event": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "timestamp": {
                "type": "long"
              }
            }
          },
          "email": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "id": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "listId": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "userId": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }
  }
}

Вот пример данных:

{
  email: 'nm1@example.com',
  userId: 'user-id',
  listId: 'list-id',
  campaignActivity: [
    { event: 'received', campaignId: 'c1', timestamp: 1 },
    { event: 'received', campaignId: 'c2', timestamp: 2 },
    { event: 'received', campaignId: 'c3', timestamp: 3 },
    { event: 'received', campaignId: 'c4', timestamp: 4 }
  ]
},
{
  email: 'nm2@example.com',
  userId: 'user-id',
  listId: 'list-id',
  campaignActivity: [
    { event: 'received', campaignId: 'c1', timestamp: 1 }
  ]
},
{
  email: 'm1@example.com',
  userId: 'user-id',
  listId: 'list-id',
  campaignActivity: []
},
{
  email: 'm2@example.com',
  userId: 'user-id',
  listId: 'list-id',
  campaignActivity: [
    { event: 'received', campaignId: 'c1', timestamp: 1 },
    { event: 'received', campaignId: 'c3', timestamp: 3 }
  ]
},
{
  email: 'm3@example.com',
  userId: 'user-id',
  listId: 'list-id',
  campaignActivity: [
    { event: 'received', campaignId: 'c2', timestamp: 2 },
    { event: 'received', campaignId: 'c3', timestamp: 3 }
  ]
}

Я хочу получить получателей, которые не получали некоторые из кампаний c2, c3 или c4 (исключая получателей, которые получили все кампании c2, c3 и c4). Это то, что я пробовал без удачи:

{
  "query": {
    "bool": {
      "must_not": [
        {
          "nested": {
            "path": "campaignActivity",
            "query": {
              "bool": {
                "filter": [
                  {
                    "term": {
                      "campaignActivity.campaignId.keyword": "c4"
                    }
                  },
                  {
                    "term": {
                      "campaignActivity.event.keyword": "received"
                    }
                  }
                ]
              }
            }
          }
        },
        {
          "nested": {
            "path": "campaignActivity",
            "query": {
              "bool": {
                "filter": [
                  {
                    "term": {
                      "campaignActivity.campaignId.keyword": "c3"
                    }
                  },
                  {
                    "term": {
                      "campaignActivity.event.keyword": "received"
                    }
                  }
                ]
              }
            }
          }
        },
        {
          "nested": {
            "path": "campaignActivity",
            "query": {
              "bool": {
                "filter": [
                  {
                    "term": {
                      "campaignActivity.campaignId.keyword": "c2"
                    }
                  },
                  {
                    "term": {
                      "campaignActivity.event.keyword": "received"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  },
  "from": 0,
  "size": 10
}

Приведенный выше запрос возвращает nm2@example.com и m1@example.com, но я ищу результат с m1@example.com, m2@example.com и m3@example.com

Чтоя делаю не так?

ОБНОВЛЕНИЕ 1:

Это самое близкое, что я получил до сих пор:

{
  "query": {
    "bool": {
      "filter": [
        {
          "nested": {
            "path": "campaignActivity",
            "query": {
              "bool": {
                "filter": [
                  {
                    "term": {
                      "campaignActivity.event.keyword": "received"
                    }
                  },
                  {
                    "terms": {
                      "campaignActivity.campaignId.keyword": [
                        "c4",
                        "c3",
                        "c2"
                      ]
                    }
                  }
                ]
              }
            }
          }
        }
      ],
      "should": [
        {
          "nested": {
            "path": "campaignActivity",
            "query": {
              "bool": {
                "must_not": [
                  {
                    "term": {
                      "campaignActivity.campaignId.keyword": "c4"
                    }
                  },
                  {
                    "term": {
                      "campaignActivity.event.keyword": "received"
                    }
                  }
                ]
              }
            }
          }
        },
        {
          "nested": {
            "path": "campaignActivity",
            "query": {
              "bool": {
                "must_not": [
                  {
                    "term": {
                      "campaignActivity.campaignId.keyword": "c3"
                    }
                  },
                  {
                    "term": {
                      "campaignActivity.event.keyword": "received"
                    }
                  }
                ]
              }
            }
          }
        },
        {
          "nested": {
            "path": "campaignActivity",
            "query": {
              "bool": {
                "must_not": [
                  {
                    "term": {
                      "campaignActivity.campaignId.keyword": "c2"
                    }
                  },
                  {
                    "term": {
                      "campaignActivity.event.keyword": "received"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  },
  "from": 0,
  "size": 10
}

Но все равно возвращаетсяnm1@example.com, который не должен быть частью результата, так как он получил все кампании (c2, c3, c4) и отсутствует m1@example.com.

1 Ответ

0 голосов
/ 22 мая 2018

Мне удалось заставить его работать с этим запросом:

{
  "query": {
    "bool": {
      "must": [
        {
          "bool": {
            "should": [
              {
                "bool": {
                  "must_not": [
                    {
                      "nested": {
                        "path": "campaignActivity",
                        "query": {
                          "bool": {
                            "filter": {
                              "exists": {
                                "field": "campaignActivity"
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              },
              {
                //match c2
              },
              {
                //match c3
              },
              {
                //match c4
              }
            ]
          }
        },
        {
          "bool": {
            "must_not": [
              {
                "bool": {
                  "must": [
                    {
                      //match c2
                    },
                    {
                      //match c3
                    },
                    {
                      //match c4
                    }
                  ]
                }
              }
            ]
          }
        }
      ]
    }
  }
}

Я надеюсь, что это будет полезно для кого-то в будущем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...