2013-07-23 118 views
3

我有这样的文件在我的索引:Elasticsearch精确匹配或查询

{ 
    "field" : "a, b, c, d, e" 
} 

域值由数组字符串函数做了一个字符串。因此,并非每个文档都具有相同的字符串,但每个文档的值至少为"a, b"

现在我想有它匹配2种文档的查询:

文件仅具有(恰好)"a, b"作为字段值或包含在该领域至少两个searchterms文件。

基本上我的问题是,如果字段得到分析,我不能满足第一个条件,如果字段没有得到分析,我不能满足第二个条件。是否有没有克隆字段为not_alanyzed的解决方案? 。

如果我克隆领域一个没有分析字段(代码示例FIELD1)我可以用这个查询我觉得像这样的查询是实现过于复杂...:

{ 
    "query": { 
    "filtered": { 
     "query": { 
     "match_all": {} 
     }, 
     "filter": { 
     "or": [ 
      { 
      "term": { 
       "field1": "a, b" 
      } 
      }, 
      { 
      "and": [ 
       { 
       "term": { 
        "field": "c" 
       } 
       }, 
       { 
       "term": { 
        "field1": "d" 
       } 
       } 
      ] 
      } 
     ] 
     } 
    } 
    } 
} 
+0

您目前如何满足“在该字段中至少包含两个搜索词的文档”的条件?您可以请发布只有这种条件搜索文档的代码吗?我可能会帮助... – ramseykhalaf

+0

代码示例中的和过滤器正在满足您提到的第二个条件... – MeiSign

+0

您是否设法解决该问题? – ramseykhalaf

回答

5

你可以使用多场映射,这允许一次发送一个字段,但是以两种不同的方式分析:

"properties": { 
    "field" { 
    "type": "multi_field", 
     "fields" : { 
     "field" : {"type" : "string", "index" : "analyzed"}, 
     "raw" : {"type" : "string", "index" : "not_analyzed"} 
    } 
    } 
} 

文档发送到elasticsearch为正常(它会被收录在两个地方,field(或field.field)和field.raw

现在,您的查询将是这样的:

{ 
    "query": { 
    "filtered": { 
     "query": { 
     "match_all": {} 
     }, 
     "filter": { 
     "or": [ 
      { 
      "term": { 
       "field.raw": "a, b" 
      } 
      }, 
      { 
      "and": [ 
       { 
       "term": { 
        "field": "c" 
       } 
       }, 
       { 
       "term": { 
        "field": "d" 
       } 
       } 
      ] 
      } 
     ] 
     } 
    } 
    } 
} 

这不是最优雅的方案。我更喜欢改变你存储数据的方式。它看起来像“a,b”代表不同的东西,也许在文档上有一个布尔型字段“a_b_only”来过滤。

祝你好运,请随时索取更多帮助!

+0

感谢您的建议,我创建了一个额外的布尔字段,同时索引,并可以使用一个简单的查询来获取所有文档只包含“a,b” – MeiSign

1

出于好奇,你为什么首先从你的数组中创建一个字符串? ES文档中的字段可以保存多个值,您可以使用“词条”过滤条件查询它们:http://www.elasticsearch.org/guide/reference/query-dsl/terms-filter/。因此,而不是原来的场数据:

{ 
    "field1" : "a, b, c, d, e" 
} 

你只是把它放在一个数组,像这样:

{ 
    "field1" : ["a", "b", "c", "d", "e"] 
} 

,然后你会询问这样的事情(注意,这是未经测试!):

{ 
    "query": { 
    "filtered": { 
     "query": { 
     "match_all": {} 
     }, 
     "filter": { 
     "or": [ 
      { 
      "terms": { 
       "field1": ["a", "b"], 
       "execution": "and" 
      } 
      }, 
      { 
      "terms": { 
       "field1": ["c", "d"], 
       "execution": "and" 
      } 
      } 
     ] 
     } 
    } 
    } 
} 

最后一点,我认为你的真实数据要求“字段1”被设置为“not_analyzed”。

+0

这不适用于我,因为所有field1值包含“a”,“ b“,但只有一些完全包含(仅)”a“,”b“。您的查询将匹配我的每个文档....这也是我将数组转换为字符串的原因。因为我需要完全匹配。 – MeiSign

+0

啊,是的,我明白你现在的意思。我误解了这个问题 - 我很高兴你找到了解决方案! –

3

multi_fields没有在Elasticsearch 1.x版本支持改用

"title" :{ 
      "type" : "string", 
      "raw" : {"type" :"string" , "index" :"not_analyzed" 
     } 

欲了解更多信息,请阅读Elasticsearch 1.7 Docs on Multi-fields