使用Elasticsearch

时间:2017-06-08 16:42:27

标签: elasticsearch edifact

我目前正在开始使用Elasticsearch。我已将一些EDIFACT消息编入索引(一种史前数据格式;-) 内容看起来像这样:

UNB+UNOA:2+SENDER+RECEIVER+170509:0050+152538'
UNH+66304+CODECO:D:95B:UN:ITG12'
BGM+34+INGATE OF UCN ABCD+9'

当我搜索短语UNH + 66304 + CODECO:D:95B时,它应该只返回一个命中,但似乎它返回包含任何这些词的所有文件(并且UNH在每个单词中文档)。 我的查询是这样的:

curl -XGET --netrc-file ~/curl_user  'localhost:9200/edi/message/_search?pretty' -H 'Content-Type: application/json' -d'
{
    "query":{
        "match":{"MESSAGE":"UNH+66304+CODECO:D:95B"}
    }
}'

我试图添加"和"像这样的运算符:

"match":{
              "MESSAGE":{
                "query":"UNH+66304+CODECO",
                "operator": "and"

              }
            }

但是没有返回任何结果。 我在这里阅读了这个建议:Searching for exact phrase 我需要使用双引号。我已经尝试过"查询":"' UNH + 66304 + CODECO'"和"查询":" \" UNH + 66304 + CODECO \""但它并没有什么不同。

我也尝试过match_phrase

"match_phrase":{
              "MESSAGE":{
                "query":"UNH+66304+CODECO"

              }
            }

不会返回结果

"match_phrase":{
              "MESSAGE":{
                "query":"UNH+66304"

              }
            }

一样。 使用普通文本似乎可以工作但是Elasticsearch不太喜欢搜索字符串中的+:etc(不幸的是EDIFACT的一部分)。

How to make query_string search exact phrase in ElasticSearch谈到使用不同的分析器,如果你想要完全匹配?

更新: abhishek mishra确认分析仪可能是要走的路。我使用的是Elasticsearch 5.4,有很多分析器可供选择:https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-analyzers.html

关键字分析器可能会映射到abhishek所建议的“未分析”字样。因为它是一个noop分析仪。但是我有点担心使用它,因为消息可能很长。对搜索的性能影响是什么?如果我使用关键字分析器,我仍然可以搜索整个消息的部分内容吗?

我想知道模式分析器是否合适? EDIFACT消息由以3个​​大写字母字符开头的段组成,并由' (但是你可以通过在前面添加?来逃避')

FTX+AAA++It?'s a strange data format'
FTX+AAA++Yes it is'

所以上面的例子是两段。如果我使用一个分隔这些段的模式,这是一个很好的匹配吗?

唯一的问题是,目前MESSAGE字段可以包含EDIFACT消息和XML消息。使用相同的模式分析器是行不通的,我想我必须创建两种不同的类型,具体取决于MESSAGE字段的内容(其余的都是相同的)。

第二次更新: 我按照建议去研究分析仪。我认为关键字分析器可能不是一个好主意,因为文本可能很长。我发现模式分析器(没有任何自定义模式)工作得非常好。它将所有内容分开:和+。像

这样的搜索
{
    "query":{
        "match_phrase":{"MESSAGE":"RFF+ABT:ATB150538080520172452"}
    }
}

{
        "query":{
            "match_phrase":{"MESSAGE":"RFF+ABT:ATB150538080520172452"}
        }
    }

现在工作。之前的问题是,例如被分成[rff,abt:atb150538080520172452]。

3 个答案:

答案 0 :(得分:1)

你在关于分析仪的正确轨道上。如果您查看类型映射,则属性MESSAGE可能标记为analyzed。这就是为什么在索引它时摆脱特殊字符的原因。您需要将其标记为not_analyzed

如果您告诉我们您的类型映射的样子,我可以帮助您正确设置。

其中一个例子 -

如果你的ES版本是< 5.0和你的类型映射看起来类似于这个 -

{

  "MESSAGE": {
    "type" "string",
    "index": "analyzed"
  }
}

将其更改为

{
  "MESSAGE": {
    "type" "string",
    "index": "not_analyzed"
  }
}

答案 1 :(得分:1)

解决方案是使用模式分析器。无需进一步配置(未指定自定义模式),它会沿着非字/数字字符分解EDIFACT消息。

标准分析仪的问题在于它表现为奇怪的':'。 所以,如果你是有RFF + ATB:AB12345;它将其分解为[rff,atb:ab12345]所以搜索ab12345并没有返回任何内容。

您可以使用

测试分析器或标记器的工作方式
curl -XPOST --netrc-file ~/curl_user 'localhost:9200/_analyze?pretty' -H 'Content-Type: application/json' -d'
{
  "analyzer": "standard",
  "text":      "UNB+UNOA:2+SENDER+RECEIVER+170513:0452+129910165"
}'

如果您只想测试使用的标记生成器,可以使用标记生成器替换'analyzer'。

答案 2 :(得分:0)

我认为你有"查询"和" match_phrase"倒:

你可以这样试试吗:

{
    "query": {
        "match_phrase": {
            "MESSAGE": "UNH+66304"
        }
    }
}