社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Elasticsearch

如何使用ElasticSearch筛选查询结果

scott • 6 年前 • 982 次点击  

我正在尝试创建一个组件,它为用户和组提供预先输入的自动完成建议。我用的是ElasticSearch 6.5.3。我创建了一个索引,其中包含要搜索的字段和3个要筛选的附加字段(isgroup、isuser、organizationid)。在某些情况下,我希望使用此组件搜索所有用户和组,有时仅搜索用户或组,或者仅搜索属于特定组织的用户。我计划根据具体的用例提供一个过滤器和搜索词。我正在使用Nest进行搜索,但我不知道如何进行搜索。是否可以这样做?如果可以,怎么做?我是不是走错了路?我主要是跟着这个 guide 创建分析器和资料。如果这有帮助的话,我可以把我的索引贴出来,但有点长。

这是一个包含两个返回项的搜索。

 return client.Search<UserGroupDocument>(s => s
            .Query(q=>q
                .QueryString(qs=>qs.Query("adm"))                    
            )
        );

    {
    "_index": "users_and_groups_autocomplete_index",
    "_type": "usergroupdocument",
    "_id": "c54956ab-c50e-481c-b093-f9855cc74480",
    "_score": 2.2962174,
    "_source": {
        "id": "c54956ab-c50e-481c-b093-f9855cc74480",
        "isUser": true,
        "isGroup": false,
        "name": "admin",
        "email": "admin@snapshotdesign.com",
        "organizationId": 2
    }
},
    {
        "_index": "users_and_groups_autocomplete_index",
        "_type": "usergroupdocument",
        "_id": "80f98d24-39e3-475d-9cb6-8f16ca472525",
        "_score": 0.8630463,
        "_source": {
        "id": "80f98d24-39e3-475d-9cb6-8f16ca472525",
        "isUser": false,
        "isGroup": true,
        "name": "new Group",
        "users": [
            {
                "name": "Test User 1",
                "email": "test@example.com"
            },
            {
                "name": "admin",
                "email": "admin@snapshotdesign.com"
            }
        ],
        "organizationId": 0
    }
},

因此,根据我在何处使用此组件,我可能需要所有这些返回,只有用户、组或组织2中的用户。

这是我的usergroupdocument类

public class UserGroupDocument
{
    public string Id { get; set; }
    public bool IsUser { get; set; }
    public bool IsGroup { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public List<User> Users { get; set; }
    public long OrganizationId { get; set; }

}

和用户类

public class User
{
    public string Name { get; set; }
    public string Email { get; set; }
}

根据下面RussCam的回答,我修改了下面所示的必须声明。这给了我想要的过滤,但没有排字功能。在我开始比赛之前,我仍然需要打字和完整的单词。

.Must(mu => mu
    .QueryString(mmp => mmp
        .Query(searchTerms)
        .Fields(f => f
            .Field(ff => ff.Name)
            .Field(ff => ff.Users.Suffix("name"))
        )
    )
)

这是我使用的索引。

{
"users_and_groups_autocomplete_index": {
    "aliases": {},
    "mappings": {
        "usergroupdocument": {
            "properties": {
                "email": {
                    "type": "text",
                    "fields": {
                        "autocomplete": {
                            "type": "text",
                            "analyzer": "autocomplete"
                        }
                    }
                },
                "id": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "isGroup": {
                    "type": "boolean"   
                },
                "isUser": {
                    "type": "boolean"
                },
                "name": {
                    "type": "text",
                    "fields": {
                        "autocomplete": {
                            "type": "text",
                            "analyzer": "autocomplete"
                        }
                    }
                },
                "organizationId": {
                    "type": "long"
                },
                "users": {
                    "properties": {
                        "email": {
                            "type": "text",
                            "fields": {
                                "autocomplete": {
                                    "type": "text",
                                    "analyzer": "autocomplete"
                                }
                            }
                        },
                        "name": {
                            "type": "text",
                            "fields": {
                                "autocomplete": {
                                    "type": "text",
                                    "analyzer": "autocomplete"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "settings": {
        "index": {
            "number_of_shards": "5",
            "provided_name": "users_and_groups_autocomplete_index",
            "creation_date": "1548363729311",
            "analysis": {
                "analyzer": {
                    "autocomplete": {
                        "filter": [
                            "lowercase"
                        ],
                        "type": "custom",
                        "tokenizer": "autocomplete"
                    }
                },
                "tokenizer": {
                    "autocomplete": {
                        "token_chars": [
                            "digit",
                            "letter"
                        ],
                        "min_gram": "1",
                        "type": "edge_ngram",
                        "max_gram": "20"
                    }
                }
            },
            "number_of_replicas": "1",
            "uuid": "Vxv-y58qQTG8Uh76Doi_dA",
            "version": {
                "created": "6050399"
            }
        }
    }
}
}
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/30729
 
982 次点击  
文章 [ 1 ]  |  最新文章 6 年前
Russ Cam
Reply   •   1 楼
Russ Cam    6 年前

您要寻找的是将多个查询组合在一起的方法:

  1. 查询搜索词
  2. 查询 isGroup
  3. 查询 isUser
  4. 查询 organizationId

并使用这些组合执行搜索。这是类似 bool query 进来。给出以下POCO

public class UserGroupDocument 
{
    public string Name { get; set; }
    public bool IsGroup { get; set; }
    public bool IsUser { get; set; }
    public string OrganizationId { get; set; }
}

我们可以从

private static void Main()
{
    var defaultIndex = "default-index";
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200")); 
    var settings = new ConnectionSettings(pool)
        .DefaultIndex(defaultIndex);

    var client = new ElasticClient(settings);

    var isUser = true;
    var isGroup = true;
    var organizationId = "organizationId";

    var searchResponse = client.Search<UserGroupDocument>(x => x
        .Index(defaultIndex)
        .Query(q => q
            .Bool(b => b
                .Must(mu => mu
                    .QueryString(mmp => mmp
                        .Query("some admin")
                        .Fields(f => f
                            .Field(ff => ff.Name)
                        )
                    )
                )
                .Filter(fi => 
                    {
                        if (isUser)
                        {
                            return fi
                                .Term(f => f.IsUser, true);
                        }

                        return null;
                    }, fi =>
                    {
                        if (isGroup)
                        {
                            return fi
                                .Term(f => f.IsGroup, true);
                        }

                        return null;
                    }, fi => fi
                    .Term(f => f.OrganizationId, organizationId)
                )
            )
        )
    );
}

这将生成以下查询

POST http://localhost:9200/default-index/usergroupdocument/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "isUser": {
              "value": true
            }
          }
        },
        {
          "term": {
            "isGroup": {
              "value": true
            }
          }
        },
        {
          "term": {
            "organizationId": {
              "value": "organizationId"
            }
          }
        }
      ],
      "must": [
        {
          "query_string": {
            "fields": [
              "name"
            ],
            "query": "some admin"
          }
        }
      ]
    }
  }
}

如果

  • 伊塞尔 false , the term 查询筛选器 伊塞尔 字段将不包括在搜索查询中
  • IS-群 , the 学期 查询筛选器 IS-群 字段将不包括在搜索查询中
  • 组织ID null 或空字符串, 学期 查询筛选器 组织ID 不会包含在搜索查询中。

现在,我们可以走得更远 IS-群 伊塞尔 可空布尔值( bool? )然后,当其中一个值为 无效的 ,各自的 学期 发送到ElasticSearch的搜索查询中将不包含查询筛选器。这利用了一个称为 无条件的 Nest中的查询,旨在使编写更复杂的查询更容易。此外,我们可以使用 operator overloading on queries 使书写更容易 布尔 查询。这意味着我们可以将查询细化到

bool? isUser = true;
bool? isGroup = true;
var organizationId = "organizationId";

var searchResponse = client.Search<UserGroupDocument>(x => x
    .Index(defaultIndex)
    .Query(q => q
        .QueryString(mmp => mmp
            .Query("some admin")
            .Fields(f => f
                .Field(ff => ff.Name)
            )
        ) && +q
        .Term(f => f.IsUser, isUser) && +q
        .Term(f => f.IsGroup, isGroup) && +q
        .Term(f => f.OrganizationId, organizationId)
    )
);