当前位置: 首页 > 知识库问答 >
问题:

检索仅包含允许标签的文档(完全相等)

戚甫
2023-03-14

对于每个搜索请求,我都允许标签列表。例如,

["search", "open_source", "freeware", "linux"]

我想检索列表中所有标签的文档。我想找回:

{
    "tags": ["search", "freeware"]
}

并排除

{
    "tags": ["search", "windows"]
}

因为列表不包含windows标签。

在Elasticsearch留档中有一个恰好等于的示例:

https://www.elastic.co/guide/en/elasticsearch/guide/current/_finding_multiple_exact_values.html

首先,我们包含一个字段,用于维护标签的数量:

{ "tags" : ["search"], "tag_count" : 1 }
{ "tags" : ["search", "open_source"], "tag_count" : 2 }

其次,我们检索所需的tag_count

GET /my_index/my_type/_search
{
    "query": {
        "filtered" : {
            "filter" : {
                 "bool" : {
                    "must" : [
                        { "term" : { "tags" : "search" } }, 
                        { "term" : { "tags" : "open_source" } }, 
                        { "term" : { "tag_count" : 2 } } 
                    ]
                }
            }
        }
    }
}

问题是我不知道tag_count

此外,我还尝试使用script\u字段tags\u count,在术语查询中写入每个允许的标记,并将minimal\u should\u match设置为tags\u count,但我无法在minimal\u should\u match中设置脚本变量。

我能调查什么?

共有3个答案

袁鸿畅
2023-03-14

为什么不在windows被添加到must not子句时使用bool呢。我希望这就是你想要的。

支智志
2023-03-14

如果索引大小为中等大小,标记基数相当低,我只会使用术语聚合来获得不同的标记,并创建必须不得过滤器来过滤掉包含“不允许”的标记的文档。有很多方法可以将所有标签的列表缓存到内存数据库中,比如Redis,我想到了以下几个方法:

  1. 有几分钟或几小时的生存时间,如果缓存已过期,请重新生成列表

一种更高效、100%准确的方法可能是这样的:

  1. 查询所有具有所需标签但不包括具有已知其他标签的文档(与第一个解决方案相同)
  2. 查看退回文件列表
  3. 如果一个文档包含一个“不允许”的标记,这意味着它不在已知标记缓存中,因此必须添加到那里,将该文档从结果集中排除
  4. Redis上的标签可以有一个TTL,比如一天或一周,这样旧标签就会被自动删除,你可以得到更简单的ES查询

这样,您就不需要备份进程来维护标签列表或使用可能很重的术语聚合,因为它会访问所有文档,并且始终获得正确的结果集和性能相当好的查询。

如果使用后续聚合,这将不起作用,因为ES可能返回错误的文档,这些文档在客户端被删减。但是,也可以通过添加术语聚合来检测,并确认它没有意外的标记。如果确实需要添加到标记缓存中,则添加到必须_not过滤器中,并且必须重新执行查询。如果频繁创建新标记,这并不理想。

闻飞跃
2023-03-14

所以我承认这不是一个很好的解决方案,但也许它会激发其他更好的解决方案?

给定您正在搜索的部分记录看起来像您在帖子中的tag_count字段:

"tags" : ["search"],
"tag_count" : 1

"tags" : ["search", "open_source"],
"tag_count" : 2

你有这样一个问题:

["search", "open_source", "freeware"]

然后,您可以通过编程方式生成如下查询:

{
    "query" : {
        "bool" : {
            "should" : [
                {
                    "bool" : {
                        "should" : [
                            { "term" : { "tags" : "search" } },
                            { "term" : { "tags" : "open_source" } },
                            { "term" : { "tags" : "freeware" } },
                            { "term" : { "tag_count" : 1 } },
                        ],
                        "minimum_should_match" : 2
                    }
                },
                {
                    "bool" : {
                        "should" : [
                            { "term" : { "tags" : "search" } },
                            { "term" : { "tags" : "open_source" } },
                            { "term" : { "tags" : "freeware" } },
                            { "term" : { "tag_count" : 2 } },
                        ],
                        "minimum_should_match" : 3
                    }
                },
                {
                    "bool" : {
                        "should" : [
                            { "term" : { "tags" : "search" } },
                            { "term" : { "tags" : "open_source" } },
                            { "term" : { "tags" : "freeware" } },
                            { "term" : { "tag_count" : 3 } },
                        ],
                        "minimum_should_match" : 4
                    }
                }
            ],
            "minimum_should_match" : 1
        }
    }
}

嵌套bool查询的数量将与查询标记的数量匹配(出于许多原因,这不是很好——但是对于较小的查询/较小的索引,可能可以解决这个问题?)。基本上,每一个子句都会处理每一个可能的tag_count情况,最小的应匹配的是tag_count 1(因此匹配tag_count和适当的tag数量-tag_count amount)。

 类似资料:
  • 我的问题是:我有两个标签。 我的目标是单击只包含单词“word”而不包含“microsoft word”的标签。 所以我做了这个: 但是这种方法让我点击包含“单词”的标签,而不等于“单词”,所以我点击的标签是第一个,而不是我想要的第二个。 我必须找到一种方法来检查等式,但我没有找到。 我能怎么办?

  • 当我用R在web上抓取研究文章时,我遇到了HTML代码,其中a

  • 问题内容: 我有一个JTextArea,它只需要接受数字。这是我的代码: 对正数有效,但对负数无效。我该如何解决? 编辑:抱歉,在Internet上找到了AxisJTextFilter,而我忘记了这一点。它的代码是: 问题答案: 尝试修改正则表达式(int验证方法containsOnlyNumbers)。 这将接受以下数字: 1234 -1234 +1234 1234.1234 希望对您有所帮助

  • 问题内容: 通过以下查询,我得到的结果包含单词“ International”和“ Shipping”,我还得到了包含“ International”或“ Shipping”的结果。我该怎么做才能确保结果同时包含两个单词而不只是其中之一? 任何帮助将不胜感激,谢谢! 问题答案: 在每个必需的单词前添加一个,然后使用。 11.8.2。 布尔全文搜索 在实现此功能时,MySQL使用了有时称为隐式布尔逻

  • 我一直在捕捉非数字时遇到问题。 我试过了,但抓不住。如果我让它捕获非数字,但不让用户再次尝试输入。。。它完全停止了我的代码。 这是我的密码:

  • 问题内容: URI(特别是HTTP URL)是否允许包含一个或多个空格字符?如果 必须 对URL 进行编码,这是通常遵循的约定还是合法的选择? 特别是,有人可以指向RFC指出 必须 对带有空格的URL 进行编码吗? 提出问题的动机: 在对网站进行Beta测试时,我注意到某些URL的构造带有空格。Firefox似乎做对了,这让我感到惊讶!但是我希望能够将开发人员指向RFC,以便他们觉得有必要修复这些