是否可以使用elasticsearch搜索特定范围?

use*_*327 6 elasticsearch

我需要根据以下范围对文档执行文本搜索:

  1. 整个文档
  2. 段落
  3. 句子

是否可以索引文档,以便您可以根据此要求过滤查询范围?

根据答案进行编辑

我现在创建了以下索引

{
  "settings": {
    "analysis": {
      "analyzer": {
        "folding": {
          "tokenizer": "standard",
          "filter": [ "lowercase", "asciifolding" ]
        }
      }
    }
  },
  "mappings": {
    "books": {
      "properties": {
        "content": {
          "type": "string",
          "fields": {
            "english": {
              "type": "string",
              "analyzer": "english"
            },
            "folded": {
              "type": "string",
              "analyzer": "folding"
            }
          }
        },
        "author": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "language": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "source": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "title": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "fileType": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        }
      }
    },
    "sections": {
      "_parent": { "type": "books" },
      "properties": {
        "content": {
          "type": "string",
          "fields": {
            "english": {
              "type": "string",
              "analyzer": "english"
            },
            "folded": {
              "type": "string",
              "analyzer": "folding"
            }
          }
        },
        "paragraphs": {
          "type": "nested",
          "properties": {
            "paragraph": {
              "properties": {
                "page": { "type": "integer" },
                "number": { "type": "integer" },
                "html_tag": { "type": "string" },
                "content": { "type": "string" }

              }
            }
          }
        },
        "author": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "language": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "source": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "title": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "fileType": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        }
      }
    },
    "messages": {
      "properties": {
        "content": {
          "type": "string",
          "fields": {
            "english": {
              "type": "string",
              "analyzer": "english"
            },
            "folded": {
              "type": "string",
              "analyzer": "folding"
            }
          }
        },
        "paragraphs": {
          "type": "nested",
          "properties": {
            "paragraph": {
              "properties": {
                "page": { "type": "integer" },
                "number": { "type": "integer" },
                "html_tag": { "type": "string" },
                "content": { "type": "string" }

              }
            }
          }
        },
        "author": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "language": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "source": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "title": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "fileType": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这给了我以下类型:书籍,章节(父书)和消息.Sections和Messages有嵌套类型Paragraphs,我跳过了句子级别.

我现在可以对图书级别的内容,部分级别的内容执行搜索.这允许我在段落之间搜索单词.如果我想匹配段落中的两个单词,我也可以直接在段落级别上搜索.

示例:假设我有以下文档

paragraph 1: It is a beautiful warm day.
paragraph 2: The cloud is clear.
Run Code Online (Sandbox Code Playgroud)

我现在可以在内容级别上搜索漂亮的AND云并获取文档.但是,如果我使用嵌套搜索在段落级别搜索漂亮的AND云,我就不会收回文档,这就是我想要的.

我看到这个解决方案的问题是:

  1. 我需要将同一段落索引3次.一旦进入Paragraph级别,一次进入内容Section级别,一次进入内容Book级别.
  2. 我不明白我从书籍和章节之间的父/子关系中获得了什么好处.我没有找到任何使用突出显示同时搜索的方法.
  3. 我需要一个单独的Message类型,它与没有parent的Section类型完全相同.没有父母的孩子没有办法,所以我可以避免额外的类型?

paw*_*que 4

为了实现这一点,您可以索引所有句子,并与句子的单词一起包含有关封闭上下文的信息,即给定句子在哪个段落、章节和书籍中。

然后查询术语将返回句子以及有关章节和书籍的信息。有了这些信息,您就知道哪个句子、段落、章节或书籍的意思。

然后您只需使用您感兴趣的任何范围即可。

要索引的示例文档:

{
    "book": <book-id>,
    "chapter": <chapter-id>,
    "paragraph": <paragraph-id>,
    "sentence": <sentence-id>,
    "sentence_text": "Here comes the text from a sentence in the indexed book"
}
Run Code Online (Sandbox Code Playgroud)

问题澄清后补充答案

为了实现这一点,您可以使用存储在同一索引中的不同文档类型。然后,您可以使用一个查询,该查询将返回可能不同类型的文档(段落、书籍等)。然后通过过滤结果类型,你就得到了你想要的。这是一个例子:

全书:

POST /books/book/1
{
    "text": "It is a beautiful warm day. The cloud is clear."
}
Run Code Online (Sandbox Code Playgroud)

第一段:

POST /books/para/1
{
    "text": "It is a beautiful warm day."
}
Run Code Online (Sandbox Code Playgroud)

第2段:

POST /books/para/2
{
    "text": "The cloud is clear."
}
Run Code Online (Sandbox Code Playgroud)

查询检索文档:

POST /books/_search
{
    "query": {
        "match": {
           "text": {
                "query": "beautiful cloud",
                "operator": "and"
           }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这能解决您的问题吗?