Запрос Elasticsearch, включая документы, которые он должен исключить, и наоборот

ВАЖНОЕ РЕДАКТИРОВАНИЕ: описанная ниже логика кажется правильной. Корень моей проблемы на самом деле был вызван утилитой, которую мы использовали для отправки новых данных в базу данных ES, а не самим запросом. Я принял ответ, в котором говорится, что запрос работает по назначению.

У меня есть сервер Elasticsearch, сопоставление которого выглядит так (как выводится командой curl 'elastic:9200/resourcelibrary/_mapping):

      {
    "resourcelibrary": {
        "mappings": {
            "resource": {
                "properties": {
                    "created_at": {
                        "type": "date"
                    },
                    "created_by": {
                        "type": "text"
                    },
                    "custom_key": {
                        "type": "keyword"
                    },
                    "defaultAction": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "default_action": {
                        "type": "keyword"
                    },
                    "description": {
                        "type": "text"
                    },
                    "id": {
                        "type": "text"
                    },
                    "indexed": {
                        "type": "keyword"
                    },
                    "is_searchable": {
                        "type": "keyword"
                    },
                    "key": {
                        "type": "text"
                    },
                    "licenses": {
                        "type": "keyword"
                    },
                    "raw": {
                        "type": "text"
                    },
                    "require_priv": {
                        "type": "keyword"
                    },
                    "source": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        },
                        "fielddata": true
                    },
                    "stat": {
                        "type": "text"
                    },
                    "style_def": {
                        "type": "keyword"
                    },
                    "tags": {
                        "type": "text"
                    },
                    "thumbnail": {
                        "type": "text"
                    },
                    "title": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "type": {
                        "type": "keyword"
                    },
                    "uid": {
                        "type": "text"
                    },
                    "updated_at": {
                        "type": "date"
                    },
                    "updated_by": {
                        "type": "text"
                    }
                }
            }
        }
    }
}

С resourcelibraryколлекция совсем пустая, я добавляю в нее следующие документы:

      [
        {
            'type'         : 'video',
            'uid'          : '2c444278-e0d3-497b-9b5b-b70756b0fdc0',
            'key'          : 'test-test',
            'custom_key'   : 'test-test',
            'description'  : 'Random text just to fill up the description. Also, math',
            'privileged'   : [],
            'require_priv' : true,
            'title'        : 'Title!!!',
            'defaultAction': '9dfcdb39-6644-4023-82c3-8227ba184c02',
            'source'       : 'frontline'
        },
        {
            'type'         : 'course',
            'uid'          : '8afb5c95-c7b5-498a-abec-ae829d164964',
            'key'          : 'test-scorm',
            'custom_key'   : 'test-scorm',
            'description'  : 'SCORM!!!',
            'privileged'   : [],
            'require_priv' : true,
            'title'        : 'SCORM!!!',
            'defaultAction': '1302dead-9941-4b90-b35c-30eff4993365',
            'source'       : 'scormcloud'
        },
        {
            'type'         : 'mc',
            'uid'          : '8e66c2fa-6090-49da-91dd-d939124fef90',
            'key'          : 'test-mc',
            'custom_key'   : 'test-mc',
            'description'  : 'MC!!!',
            'require_priv' : false,
            'title'        : 'MC!!!',
            'defaultAction': '7957b8f5-c934-4296-b7bb-70f2cc4b2ad0',
            'source'       : 'edivate'
        },
        {
            'type'         : 'group',
            'uid'          : '80a908c3-dd6c-4902-9f05-647a8af689ac',
            'key'          : 'test-group',
            'custom_key'   : 'test-group',
            'description'  : 'GROUP!!!',
            'require_priv' : false,
            'title'        : 'GROUP!!!',
            'defaultAction': '25b700a5-7563-4d6e-9eab-18465d08a683',
            'source'       : 'two words'
        },
        {
            'type'         : 'video',
            'uid'          : '3d555389-e0d3-497b-9b5b-c81867c10ed1',
            'key'          : 'test-video',
            'custom_key'   : 'test-video',
            'description'  : 'Random text just to fill up the description. Also, science',
            'require_priv' : false,
            'title'        : 'NO-PRIVS-REQUIRED RESOURCE!!!',
            'defaultAction': '9dfcdb39-6644-4023-82c3-8227ba184c02',
            'source'       : 'ets'
        },
        {
            'type'         : 'video',
            'uid'          : 'fbc0f853-9020-4ed7-8d4d-e18ebe75d815',
            'key'          : 'test-test-test',
            'custom_key'   : 'test-test-test',
            'description'  : 'integration testing description',
            'require_priv' : false,
            'title'        : 'Search All Resources Integration Title',
            'defaultAction': '9dfcdb39-6644-4023-82c3-8227ba184c02'
        },
        {
            'type'         : 'file',
            'uid'          : 'cf84e252-1082-4a94-9fe5-45fa73364e2f',
            'key'          : 'test-test-test two',
            'custom_key'   : 'test-test-test two',
            'description'  : 'integration testing description two',
            'require_priv' : false,
            'title'        : 'Search All Resources Integration Title two',
            'defaultAction': '0b7abf9e-c88a-4d19-891d-52fe0b220506'
        },
        {
            'id'           : 'ba462b70-de73-4173-88bf-66bc9d1385b9',
            'type'         : 'course',
            'uid'          : 'scormcloud-course-cf84e252-1082-4a94-9fe5-45fa73364e2f',
            'key'          : 'test-test-test two',
            'custom_key'   : 'test-test-test two',
            'description'  : 'integration testing description two',
            'require_priv' : false,
            'title'        : 'Search All Resources Integration Title two',
            'defaultAction': '0b7abf9e-c88a-4d19-891d-52fe0b220506'
        },
        {
            'id'           : '7f0cbbc6-a1dd-43ca-9108-b31f90904dce',
            'type'         : 'course',
            'uid'          : 'scormcloud-course-7f0cbbc6-a1dd-43ca-9108-b31f90904dce',
            'key'          : 'LD_7f0cbbc6-a1dd-43ca-9108-b31f90904dce',
            'custom_key'   : 'LD_7f0cbbc6-a1dd-43ca-9108-b31f90904dce',
            'description'  : 'This is a LearningDesigner course',
            'require_priv' : false, // Still requires LCR Tooling
            'title'        : 'LearningDesigner Course 1',
            'defaultAction': '1302dead-9941-4b90-b35c-30eff4993365'
        },
        {
            'id'           : '9e195a62-1a53-42c0-8648-4aa35c309d48',
            'type'         : 'course',
            'uid'          : 'scormcloud-course-9e195a62-1a53-42c0-8648-4aa35c309d48',
            'key'          : 'user-SCORM_9e195a62-1a53-42c0-8648-4aa35c309d48',
            'custom_key'   : 'user-SCORM_9e195a62-1a53-42c0-8648-4aa35c309d48',
            'description'  : 'This is a user-uploaded SCORM course',
            'require_priv' : false, // Still requires LCR Tooling
            'title'        : 'User-Uploaded Course 1',
            'defaultAction': '1302dead-9941-4b90-b35c-30eff4993365'
        },
        {
            'id'           : '2b1b2197-48ae-4669-8bfa-7edd440cb027',
            'type'         : 'course',
            'uid'          : 'course-2b1b2197-48ae-4669-8bfa-7edd440cb027',
            'source'       : 'canvas',
            'key'          : '9e195a62-1a53-42c0-8648-4aa35c309d48',
            'custom_key'   : '9e195a62-1a53-42c0-8648-4aa35c309d48',
            'description'  : 'This is a Canvas course',
            'require_priv' : false,
            'title'        : 'Canvas Course 1',
            'defaultAction': '7aef5ef2-e0c1-4188-9e74-3e24057e7e6e'
        },
        {
            'id'           : '5e113295-f905-4a3d-97e0-f5d49926c979',
            'type'         : 'collaborative',
            'uid'          : 'frontline-collaborative-5e113295-f905-4a3d-97e0-f5d49926c979',
            'key'          : '5e113295-f905-4a3d-97e0-f5d49926c979',
            'custom_key'   : '5e113295-f905-4a3d-97e0-f5d49926c979',
            'description'  : 'This is a Collaborative resource',
            'require_priv' : false,
            'title'        : 'Collab Resource 1',
            'defaultAction': 'e153409d-3330-4202-baf2-d602b4cb7d66'
        },
    ]

Я работаю с BodyBuilder.JS, чтобы создать запрос, который возвращает все, КРОМЕ документов, которые соответствуют любому из следующих критериев:

  • равно "совместному"
  • равно "холсту"
  • равен «курсу» И начинается с «LD_»
  • равно «курсу» И начинается с «user-SCORM_»

В моем приложении я реализовал эти эксклюзивные условия так (примечание: bodyобъект, созданный с помощью bodybuilder()функция из BodyBuilder.JS):

      body.notFilter('term', 'type', 'collaborative');
body.notFilter('term', 'source', 'canvas');
body.notFilter('bool', subFilter => {
    subFilter.filter('term', 'type', 'course');
    subFilter.filter('regexp', 'custom_key', 'LD_.*');
    return subFilter;
});
body.notFilter('bool', subFilter => {
    subFilter.filter('term', 'type', 'course');
    subFilter.filter('regexp', 'custom_key', 'user-SCORM_.*');
    return subFilter;
});

... И когда body.build()вызывается, он создает следующую строку Elasticsearch DSL:

      {
  "from": "0",
  "size": 100,
  "query": {
    "bool": {
      "filter": {
        "bool": {
          "must": {
            "bool": {}
          },
          "must_not": [
            {
              "term": {
                "type": "collaborative"
              }
            },
            {
              "term": {
                "source": "canvas"
              }
            },
            {
              "bool": {
                "must": [
                  {
                    "term": {
                      "type": "course"
                    }
                  },
                  {
                    "regexp": {
                      "custom_key": "LD_.*"
                    }
                  }
                ]
              }
            },
            {
              "bool": {
                "must": [
                  {
                    "term": {
                      "type": "course"
                    }
                  },
                  {
                    "regexp": {
                      "custom_key": "user-SCORM_.*"
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    }
  }
}

Когда я отправляю этот запрос на свой сервер Elasticsearch, он правильно пропускает документы с «совместными» и sourceиз «холста». Однако он делает следующие неправильные вещи:

  1. в результатах поиска отсутствует второй документ ( uidзначение "8afb5c95-c7b5-498a-abec-ae829d164964")
  2. результаты поиска неправильно включают документы, чей "курс" и начинается с "LD_"
  3. результаты поиска неправильно включают документы, чьи type"курс" и чей custom_keyначинается с "user-SCORM_"

Я искренне не уверен, что я делаю неправильно здесь. Я также попытался заменить regexpподпункты с matchподпункты (например, subFilter.filter('match', 'custom_key', 'LD_*'), но я получаю точно такие же результаты.

Я смотрел на эту штуку буквально неделю, пробовал сотни немного разных вещей, похожих на то, что описано в этом посте, но это самое близкое к получению нужных мне результатов. Что я делаю не так?

1 ответ

Это может помочь решить и проанализировать вашу проблему локально.

Я создал индекс:

PUT /библиотека ресурсов

      {
  "mappings": {
    "properties": {
      "created_at": {
        "type": "date"
      },
      "created_by": {
        "type": "text"
      },
      "custom_key": {
        "type": "keyword"
      },
      "defaultAction": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "default_action": {
        "type": "keyword"
      },
      "description": {
        "type": "text"
      },
      "id": {
        "type": "text"
      },
      "indexed": {
        "type": "keyword"
      },
      "is_searchable": {
        "type": "keyword"
      },
      "key": {
        "type": "text"
      },
      "licenses": {
        "type": "keyword"
      },
      "raw": {
        "type": "text"
      },
      "require_priv": {
        "type": "keyword"
      },
      "source": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        },
        "fielddata": true
      },
      "stat": {
        "type": "text"
      },
      "style_def": {
        "type": "keyword"
      },
      "tags": {
        "type": "text"
      },
      "thumbnail": {
        "type": "text"
      },
      "title": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "type": {
        "type": "keyword"
      },
      "uid": {
        "type": "text"
      },
      "updated_at": {
        "type": "date"
      },
      "updated_by": {
        "type": "text"
      }
    }
  }
}

Прием данных:

POST /resourcelibrary/_doc

      {
  "custom_key": "5e113295-f905-4a3d-97e0-f5d49926c979",
  "defaultAction": "e153409d-3330-4202-baf2-d602b4cb7d66",
  "description": "This is a Collaborative resource",
  "id": "5e113295-f905-4a3d-97e0-f5d49926c979",
  "key": "5e113295-f905-4a3d-97e0-f5d49926c979",
  "require_priv": false,
  "title": "Collab Resource 1",
  "type": "collaborative",
  "uid": "frontline-collaborative-5e113295-f905-4a3d-97e0-f5d49926c979"
}

Поисковый запрос (работает нормально)

ПОЛУЧИТЬ /resourcelibrary/_search

      {
  "query": {
    "bool": {
      "filter": {
        "bool": {
          "must": {
            "bool": {}
          },
          "must_not": [
            {
              "term": {
                "type": "collaborative"
              }
            },
            {
              "term": {
                "source": "canvas"
              }
            },
            {
              "bool": {
                "must": [
                  {
                    "term": {
                      "type": "course"
                    }
                  },
                  {
                    "regexp": {
                      "custom_key": "LD_.*"
                    }
                  }
                ]
              }
            },
            {
              "bool": {
                "must": [
                  {
                    "term": {
                      "type": "course"
                    }
                  },
                  {
                    "regexp": {
                      "custom_key": "user-SCORM_.*"
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    }
  }
}

Попробуйте создать индекс с другим именем и попробуйте выполнить эти запросы. Таким образом, вы можете отлаживать реальную проблему.

Но запрос генерируется правильно.

Другие вопросы по тегам