java - 弹性搜索:如何在单个索引中搜索两个文档?
问题描述
我在一个名为inventory 的索引中配置了两个文档。
- 个人资料(这有用户和移动信息)
- p2p关系
库存索引映射属性如下:
{
"mappings": {
"properties": {
"type": {"type": "keyword"},
"id": {"type": "keyword"},
"sourceId": {"type": "keyword"},
"targetId": {"type": "keyword"},
"firstName": {"type": "text"},
"lastName": {"type": "text"},
"createdBy": {"type": "text"},
"p_type": {"type": "text"},
"model": {"type": "text"},
"OS": {"type": "keyword"}
}
}
}
profile 有以下信息
用户:
{ "type":"profile", "id" : "user1", "p_type" : "user", "firstName" : "Ashok", "lastName" : "S" }
{ "type":"profile", "id" : "user2", "p_type" : "user", "firstName" : "Arun", "lastName" : "V" }
手机:
{ "type":"profile", "id" : "mobile1", "p_type" : "mobile", "model" : "samsung", "OS" : "Android" }
{ "type":"profile", "id" : "mobile2", "p_type" : "mobile", "model" : "iPhone", "OS" : "iOS" }
p2p-relation有哪个用户使用了哪个移动信息:
{ "type":"p2p-relation", "id" : "user1-owns-mobile1", "sourceId" : "user1", "targetId" : "mobile1", "createdBy" : "admin" }
{ "type":"p2p-relation", "id" : "user1-owns-mobile2", "sourceId" : "user1", "targetId" : "mobile2", "createdBy" : "admin" }
在我们的业务案例中,我们需要检索用户拥有的 android/iOS 手机列表,我们从客户那里获得输入。
也就是说,如果 user1 请求/mymobiles?query=os==Android,它应该将其转换为 ES 并期待
{ “type”:“profile”,“id”:“mobile1”,“p_type”:“mobile”,“model”:“samsung”,“OS”:“Android”}
结果,如果 user2 请求相同,它应该返回空。
我试过查询和布尔。但它只在单个文档中搜索。如何在弹性搜索中实现这一点?
解决方案
上述模型属于多对多关系数据模型。一个用户可以有许多移动电话分配给他,一个移动设备可以在一段时间内分配给许多用户。因此将数据模型更改为将其存储为嵌套对象。
{
"mappings": {
"properties": {
"type": {"type": "keyword"},
"id": {"type": "keyword"},
"firstName": {"type": "text"},
"lastName": {"type": "text"},
"createdBy": {"type": "text"},
"model": {"type": "text"},
"OS": {"type": "keyword"},
"mobiles" : {
"type" : "nested",
"properties" : {
"id": {"type": "keyword"},
"model": {"type": "text"},
"OS": {"type": "keyword"},
"createdBy": {"type": "text"}
}
},
"users" : {
"type" : "nested",
"properties" : {
"id": {"type": "keyword"},
"firstName": {"type": "keyword"},
"lastName": {"type": "keyword"},
"createdBy": {"type": "text"}
}
}
}}}
但痛苦的是,每当将手机分配给用户时,我都需要花费额外的精力来更新两行。
数据存储如下
{ "type":"profile", "id" : "user1", "firstName" : "Ashok", "lastName" : "S", "mobiles" : [ {"id" : "uuid1", "model": "samsung", "OS" : "Android"}] }
{ "type":"profile", {"id" : "uuid1", "model": "samsung", "OS" : "Android"}, "users" : [ "id" : "user1", "firstName" : "Ashok", "lastName" : "S"] }
为了回答 /mymobiles?query=os==Android,我使用了以下查询。
{
"query": {
"bool": {
"must": [
{
{ "term": {"OS": "android"} },
"nested": {
"path": "users",
"query": {
"bool": {
"must": [ {"term": {"users.id": "user1"} }]
}
}
}
}
]
}
}}
我已经参考了以下链接来执行此操作:https ://medium.com/@mena.meseha/briefly-describe-how-to-store-complex-relational-data-in-elasticsearch-f30277317b1
推荐阅读
- javascript - 没有模块的缩小 OpenLayers
- reactjs - React Trello - 卡片属性
- android - 仅下载 Android Studio ide
- c++ - 读取文件时我的 if 语句不起作用
- google-cloud-platform - 无法在 Google 工作区插件中显示 Google 用户图像
- ethereum - 减少合同规模的最简单方法
- list - 如何在 Elm 中对列表元素进行编号?
- php - 阻止从站点下载 PDF 文件
- flutter - Flutter 无法使用 Freezed 构建 build_runner
- reactjs - React Leaflet v3:创建控件的好方法