我试图确定在弹性搜索中索引文档的最佳方法.我有一个文档Doc,它有一些字段:
Doc
created_at
updated_at
field_a
field_b
Run Code Online (Sandbox Code Playgroud)
但Doc也会有一些特定于个人用户的字段.例如,field_x对于用户1将具有值"A",并且field_x将具有用于用户2的值"B".对于每个文档,将存在非常有限数量的用户(通常为2,最多~10).当用户搜索field_x时,他们必须搜索属于它们的值.我一直在探索ES中的嵌套类型.
Doc
created_at
updated_at
field_x: [{
user: 1
field_x: A
},{
user: 2
field_x: B
}]
Run Code Online (Sandbox Code Playgroud)
当用户1在field_x上搜索值"A"时,此文档应该会受到影响.但是,当用户1按值'B'搜索时,不应该这样.
但是,根据文档:
索引在doc中多次出现的内部对象时的一个问题是将发生"交叉对象"搜索匹配
有没有办法避免嵌套类型的这种行为或我应该探索另一种类型?
有关此类查询执行情况的其他信息非常有价值.仅仅从阅读文档开始,它就表明嵌套查询在性能方面与常规查询相比并没有太大差异.如果有人真正体验过这一点,我很乐意听到.
嵌套类型是您正在寻找的,并且不要过于担心性能.
在索引文档之前,您需要设置文档的映射:
curl -XDELETE localhost:9200/index
curl -XPUT localhost:9200/index
curl -XPUT localhost:9200/index/type/_mapping -d '{
"type": {
"properties": {
"field_x": {
"type": "nested",
"include_in_parent": false,
"include_in_root": false,
"properties": {
"user": {
"type": "string"
},
"field_x": {
"type": "string",
"index" : "not_analyzed" // NOTE*
}
}
}
}
}
}'
Run Code Online (Sandbox Code Playgroud)
*注意:如果您的字段实际上只包含诸如"A"和"B"之类的单数字母,则您不希望分析该字段,否则elasticsearch将删除这些单数字母"单词".如果这只是您的示例,并且在您的真实文档中,您正在搜索正确的单词,请删除此行并让elasticsearch分析该字段.
然后,索引您的文档:
curl -XPUT http://localhost:9200/index/type/1 -d '
{
"field_a": "foo",
"field_b": "bar",
"field_x" : [{
"user" : "1",
"field_x" : "A"
},
{
"user" : "2",
"field_x" : "B"
}]
}'
Run Code Online (Sandbox Code Playgroud)
并运行您的查询:
curl -XGET localhost:9200/index/type/_search -d '{
"query": {
"nested" : {
"path" : "field_x",
"score_mode" : "avg",
"query" : {
"bool" : {
"must" : [
{
"term": {
"field_x.user": "1"
}
},
{
"term": {
"field_x.field_x": "A"
}
}
]
}
}
}
}
}';
Run Code Online (Sandbox Code Playgroud)
这将导致
{"took":13,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":1,"max_score":1.987628,"hits":[{"_index":"index","_type":"type","_id":"1","_score":1.987628, "_source" :
{
"field_a": "foo",
"field_b": "bar",
"field_x" : [{
"user" : "1",
"field_x" : "A"
},
{
"user" : "2",
"field_x" : "B"
}]
}}]}}
Run Code Online (Sandbox Code Playgroud)
但是,查询
curl -XGET localhost:9200/index/type/_search -d '{
"query": {
"nested" : {
"path" : "field_x",
"score_mode" : "avg",
"query" : {
"bool" : {
"must" : [
{
"term": {
"field_x.user": "1"
}
},
{
"term": {
"field_x.field_x": "B"
}
}
]
}
}
}
}
}';
Run Code Online (Sandbox Code Playgroud)
不会返回任何结果
{"took":6,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1771 次 |
| 最近记录: |