elasticsearch,lucene,Java,elasticsearch,Lucene" /> elasticsearch,lucene,Java,elasticsearch,Lucene" />

Java 弹性搜索中的模式匹配?

Java 弹性搜索中的模式匹配?,java,elasticsearch,lucene,Java,elasticsearch,Lucene,继续我之前的工作,我已经根据femtoRgon的一些字符和锚点更改了查询,弹性搜索不支持这些字符和锚点 我正在寻找匹配“xxx xx xxxx”这样的模式的方法,以便使用弹性搜索查找带有社会保险号码的文档 让我们假设,在索引文档中,我想找到所有那些社会保险号与“xxx xx xxxx”模式匹配的文档 为文档编制索引的示例代码: InputStream is = null; try { is = new FileInputStream("/home/admin/Download

继续我之前的工作,我已经根据femtoRgon的一些字符和锚点更改了查询,弹性搜索不支持这些字符和锚点

我正在寻找匹配“xxx xx xxxx”这样的模式的方法,以便使用
弹性搜索
查找带有社会保险号码的文档

让我们假设,在索引文档中,我想找到所有那些社会保险号与“xxx xx xxxx”模式匹配的文档

为文档编制索引的示例代码:

InputStream is = null;
    try {
      is = new FileInputStream("/home/admin/Downloads/20121221.doc");
      ContentHandler contenthandler = new BodyContentHandler();
      Metadata metadata = new Metadata();
      Parser parser = new AutoDetectParser();
      parser.parse(is, contenthandler, metadata, new ParseContext());
      }
    catch (Exception e) {
      e.printStackTrace();
    }
    finally {
        if (is != null) is.close();
    } 
用于搜索的示例代码

QueryBuilder queryBuilderFullText = null;
queryBuilderFullText = QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(),
                        FilterBuilders.regexpFilter("_all", "[0-9]{3}?[0-9]{2}?[0-9]{4}"));
SearchRequestBuilder requestBuilder;
            requestBuilder = client.prepareSearch()
                    .setIndices(getDomainIndexId(project))
                    .setTypes(getProjectTypeId(project))
                    .setQuery(queryBuilderFullText);
SearchResponse response = requestBuilder.execute().actionGet(ES_TIMEOUT_MS);
            SearchHits hits = response.getHits();
if (hits.getTotalHits() > 0) {
System.out.println(hits.getTotalHits());
 } else {
                return 0l;  
        }
我在以下方面获得了成功:

45-555-5462
457-55-5462
4578-55-5462
457-55-54623
457-55-5462-23
但根据我的要求,它应该只返回“457-55-5462”(基于模式匹配“xxx xx xxxx”)


请帮助。

您忘记在正则表达式中添加
-
之前的
,必要时还可以使用锚定

"[0-9]{3}-?[0-9]{2}-?[0-9]{4}"


鉴于
^
$
\d
不能使用,我会这样做:

[^0-9-][0-9]{3}-[0-9]{2}-[0-9]{4}[^0-9-]
或在Java中:

FilterBuilders.regexpFilter("_all", "[^0-9-][0-9]{3}-[0-9]{2}-[0-9]{4}[^0-9-]"));
检查找到的数字之前或之后是否没有其他数字或破折号。不过,它确实要求在比赛前后都有一些字符,因此这不会捕获将社会保险号码作为最开始的最结束的的文档


可能重复的@funkurm我已根据femtoRgon的帖子更改了查询,因为弹性搜索不支持某些字符和锚。所以我在这里更新了我的搜索查询。是的,我注意到在标记后,但我无法撤消标记,很抱歉。我也回答说,希望这能满足你的需要:)@funkworm没问题。感谢您的帮助,但不幸的是,弹性搜索不支持
\d
\\d
字符和
^
$
锚。已更改我的答案accordingly@Ashish让我们在该答案的注释中讨论答案:P您可以从Regex101演示中看到,它适用于所有3种regex口味。我猜问题在于
FilterBuilder
弹性搜索的另一部分。是的,这可能是弹性搜索的问题。我正在考虑这个问题。谢谢你们的帮助。我认为-问题在于索引,因为当它被索引时,它并没有被索引为一个术语“457-55-5462”,而是三个术语:“457”、“55”和“5462”。这就是我的术语搜索无法找到此术语的原因<代码>弹性搜索
在索引时删除连字符:(
xxx-xx-xxxx
不是
xxx-xxxx-xx
,但是你肯定可以用空格替换
{3}
{2}
后面的
-
。我读了一些他们的正则表达式引擎,但没有什么意义。他们说
abababababab
不匹配
(…)+
FilterBuilders.regexpFilter("_all", "[^0-9-][0-9]{3}-[0-9]{2}-[0-9]{4}[^0-9-]"));