“文档” 菜单
文档首页
/
MongoDB 阿特拉斯
/ / / /

接近

在此页面上

  • 定义
  • 语法
  • 选项
  • 评分行为
  • 限制
  • 举例
near

near 操作符支持对数字、日期和字符串值进行查询和评分。此操作符可用于对以下各项执行搜索:

  • BSON int32int64double 数据类型的数字字段。

  • BSON date 类型的日期字段采用 ISODate 格式。

  • 使用纬度和经度坐标定义的地理位置字段。

可以使用 near 操作符查找接近一个数字或日期的结果。near 操作符根据与数字或日期的接近程度对 Atlas Search 结果进行评分。

near 通过以下语法实现:

{
$search: {
"index": <index name>, // optional, defaults to "default"
"near": {
"path": "<field-to-search>",
"origin": <date-or-number>,
"pivot": <pivot-distance>,
"score": <score-options>
}
}
}

near 使用以下词条来构造查询:

字段
类型
说明
必要性
origin
日期、数字或地理位置

要在附近搜索的数字、日期或地理位置。这是测量结果接近度的起点。

  • 对于数字字段,值必须是 BSON int32int64double 数据类型。

  • 对于日期字段,值必须是 ISODate 格式的日期。

  • 对于地理字段。该值必须是GeoJSON 点。

path
字符串或字符串数组
要搜索的一个或多个带索引字段。请参阅路径构造
pivot
数字

用于计算 Atlas Search 结果文档的分数的值。分数使用以下公式计算:

pivot
score = ------------------
pivot + distance

其中,distanceorigin 与索引字段值的差值。

当结果的索引字段值与 origin 相差 pivot 个单位时,结果的得分等于 1/2(或 0.5)。pivot 的值必须大于(即 >0

如果 origin 为:

  • 数字,pivot可以指定为整数或浮点数。

  • 日期,pivot必须以毫秒为单位指定,并且可以指定为 32 或 64 位整数。

    例子

    • 1 分钟等于 60,000 ms

    • 1 小时等于 3,600,000 ms

    • 1 天等于 86,400,000 ms

    • 1 个月(或 30 天)等于 2,592,000,000 ms

  • GeoJSON 点,pivot 以米为单位测量,必须指定为整数或浮点数。

score
对象

分配给匹配搜索结果的分数。您可以使用以下选项修改默认分数:

  • boost将生成的分数乘以给定数字。

  • constant将结果分数替换为给定数字。

  • function:使用给定的表达式替换结果分数。

有关在查询中使用 score 的信息,请参阅对结果中的文档进行评分

要了解更多信息,请参阅评分行为。

没有

Atlas Search score 是 Atlas Search 结果与 origin 的接近度的度量。score 的量值范围为 01,其中,1 表示精确匹配,0 表示匹配度很低。当 Atlas Search 结果与 origin 的距离等于使用 pivot 计算的距原点的距离时,分数等于 0.5

分数使用以下公式计算:

pivot
score = ------------------
pivot + distance

其中,distanceorigin 与索引字段值之间的差值。

可以在查询中使用 score 选项修改默认分数。要了解有关选项的详细信息,请参阅修改分数

即使有 Atlas Search 索引,也无法使用 near 操作符查询存储在数组中的数字或日期值。只能使用 range 操作符来查询数组内的索引数字或日期值。

数字日期示例使用sample_mflix数据库中的movies集合。 GeoJSON 点示例使用sample_airbnb数据库中的listingsAndReviews集合。

如果在 Atlas 集群上加载示例数据,则可以使用以下示例中的索引定义或动态索引来创建静态索引,并在集群上运行示例查询。

提示

如果您已经加载示例数据集,请按照 Atlas Search 入门教程,创建索引定义并运行 Atlas Search 查询。

以下示例使用 near 操作符查询数字字段。

例子

以下名为 runtimes 的索引定义对 movies 集合中的 runtime 字段值编制索引:

1{
2 "mappings": {
3 "dynamic": false,
4 "fields": {
5 "runtime": {
6 "type": "number"
7 }
8 }
9 }
10}

以下查询在movies集合中搜索runtime字段值接近279的文档。 它包括一个用于将输出限制为7个结果的$limit阶段和一个用于执行以下操作的$project阶段:

  • 排除 titleruntime 之外的所有字段

  • 添加字段 score

score 是使用 pivot 计算得出。

1db.movies.aggregate([
2 {
3 $search: {
4 "index": "runtimes",
5 "near": {
6 "path": "runtime",
7 "origin": 279,
8 "pivot": 2
9 }
10 }
11 },
12 {
13 $limit: 7
14 },
15 {
16 $project: {
17 "_id": 0,
18 "title": 1,
19 "runtime": 1,
20 score: { $meta: "searchScore" }
21 }
22 }
23])

以上查询返回以下结果:

1{ "runtime" : 279, "title" : "The Kingdom", "score" : 1 }
2{ "runtime" : 279, "title" : "The Jinx: The Life and Deaths of Robert Durst", "score" : 1 }
3{ "runtime" : 280, "title" : "Shoah", "score" : 0.6666666865348816 }
4{ "runtime" : 281, "title" : "Les Misèrables", "score" : 0.5 }
5{ "runtime" : 277, "title" : "Tokyo Trial", "score" : 0.5 }
6{ "runtime" : 276, "title" : "Warriors of the Rainbow: Seediq Bale", "score" : 0.4000000059604645 }
7{ "runtime" : 283, "title" : "Scenes from a Marriage", "score" : 0.3333333432674408 }

在上面的 Atlas Search 结果中,电影 The KingdomThe Jinx: The Life and Deaths of Robert Durst 的分数为 1.0,因为它们的 runtime 字段值 279 是完全匹配的。电影 Les MisèrablesTokyo Trial 的分数为 0.5,因为它们的 runtime 字段值与 279 相差 2 个单位。

以下示例使用 near 操作符查询日期字段。

例子

以下名为 releaseddate 的索引定义对 movies 集合中的 released 字段值编制索引:

1{
2 "mappings": {
3 "dynamic": false,
4 "fields": {
5 "released": {
6 "type": "date"
7 }
8 }
9 }
10}

以下查询搜索 9 月13 、 1前后上映的电影。 它包括一个用于将输出限制为3结果的$limit阶段和一个用于执行以下操作的$project阶段:

  • 排除 titlereleased 之外的所有字段

  • 添加字段 score

结果的 score 将使用 pivot 计算得出。

注意

pivot 此处以毫秒为单位,7,776,000,000 ms 等于大约三个月。

1db.movies.aggregate([
2 {
3 $search: {
4 "index": "releaseddate",
5 "near": {
6 "path": "released",
7 "origin": ISODate("1915-09-13T00:00:00.000+00:00"),
8 "pivot": 7776000000
9 }
10 }
11 },
12 {
13 $limit: 3
14 },
15 {
16 $project: {
17 "_id": 0,
18 "title": 1,
19 "released": 1,
20 score: { $meta: "searchScore" }
21 }
22 }
23])

以上查询会返回以下搜索结果:

{ "title" : "Regeneration", "released" : ISODate("1915-09-13T00:00:00Z"), "score" : 1 }
{ "title" : "The Cheat", "released" : ISODate("1915-12-13T00:00:00Z"), "score" : 0.49723756313323975 }
{ "title" : "Hell's Hinges", "released" : ISODate("1916-03-05T00:00:00Z"), "score" : 0.34090909361839294 }

在上面的 Atlas Search 结果中,电影 Regeneration 的分数为 1,因为 1915-09-13released 字段值是精确匹配项。在 1915-12-13 上映的电影 The Cheat 的分数约为 0.5,因为 1915-09-13released 字段值与 origin 相差约 7,776,000,000 毫秒。

以下示例使用 near 操作符查询 sample_airbnb.listingsAndReviews 集合中的 GeoJSON 点对象。以下索引定义对 listingsAndReviews 集合中的 address.locationproperty_type 字段编制索引。

例子

1{
2 "mappings": {
3 "fields": {
4 "address": {
5 "fields": {
6 "location": {
7 "type": "geo"
8 }
9 },
10 "type": "document"
11 },
12 "property_type": {
13 "type": "string"
14 }
15 }
16 }
17}

以下示例使用 near 操作符查询 sample_airbnb.listingsAndReviews 集合中的 address.location 字段。

例子

以下查询搜索葡萄牙的房产。它包括一个用于将输出限制为3结果的$limit阶段和一个用于执行以下操作的$project阶段:

  • 排除 nameaddress 之外的所有字段

  • 添加字段 score

结果的 score 将使用 pivot 计算得出。请注意,此处测量的 pivot 的单位为米,1000 米等于 1 公里。

1db.listingsAndReviews.aggregate([
2 {
3 "$search": {
4 "near": {
5 "origin": {
6 "type": "Point",
7 "coordinates": [-8.61308, 41.1413]
8 },
9 "pivot": 1000,
10 "path": "address.location"
11 }
12 }
13 },
14 {
15 $limit: 3
16 },
17 {
18 $project: {
19 "_id": 0,
20 "name": 1,
21 "address": 1,
22 score: { $meta: "searchScore" }
23 }
24 }
25])

以上查询会返回以下搜索结果:

1{
2 "name" : "Ribeira Charming Duplex",
3 "address" : {
4 "street" : "Porto, Porto, Portugal",
5 "suburb" : "",
6 "government_area" : "Cedofeita, Ildefonso, Sé, Miragaia, Nicolau, Vitória",
7 "market" : "Porto",
8 "country" : "Portugal",
9 "country_code" : "PT",
10 "location" : {
11 "type" : "Point",
12 "coordinates" : [ -8.61308, 41.1413 ],
13 "is_location_exact" : false
14 }
15 },
16 "score" : 1
17}
18{
19 "name" : "DB RIBEIRA - Grey Apartment",
20 "address" : {
21 "street" : "Porto, Porto, Portugal",
22 "suburb" : "",
23 "government_area" : "Cedofeita, Ildefonso, Sé, Miragaia, Nicolau, Vitória",
24 "market" : "Porto",
25 "country" : "Portugal",
26 "country_code" : "PT",
27 "location" : {
28 "type" : "Point",
29 "coordinates" : [ -8.61294, 41.14126 ],
30 "is_location_exact" : true
31 }
32 },
33 "score" : 0.9876177310943604
34}
35{
36 "name" : "Ribeira 24 (4)",
37 "address" : {
38 "street" : "Porto, Porto, Portugal",
39 "suburb" : "",
40 "government_area" : "Cedofeita, Ildefonso, Sé, Miragaia, Nicolau, Vitória",
41 "market" : "Porto",
42 "country" : "Portugal",
43 "country_code" : "PT",
44 "location" : {
45 "type" : "Point",
46 "coordinates" : [ -8.61318, 41.14107 ],
47 "is_location_exact" : false
48 }
49 },
50 "score" : 0.973789632320404
51}

结果显示,距离指定坐标较远的属性的得分较低。

以下示例使用 compound 操作符查询 sample_airbnb.listingsAndReviews 集合中的 property_typeaddress.location 字段。

例子

以下查询搜索指定 GeoJSON 点附近的香港公寓。 查询使用“必须”指定必须满足的Atlas Search条件,并使用“ should ”指定位置偏好。 它包括一个用于将输出限制为3结果的$limit阶段和一个用于执行以下操作的$project阶段:

  • 排除 property_typeaddress 之外的所有字段

  • 添加字段 score

score 是使用 pivot 字段计算得出。请注意,此处测量的 pivot 的单位为米,1000 米等于 1 公里。

1db.listingsAndReviews.aggregate([
2 {
3 $search: {
4 "compound": {
5 "must": {
6 "text": {
7 "query": "Apartment",
8 "path": "property_type"
9 }
10 },
11 "should": {
12 "near": {
13 "origin": {
14 "type": "Point",
15 "coordinates": [114.15027, 22.28158]
16 },
17 "pivot": 1000,
18 "path": "address.location"
19 }
20 }
21 }
22 }
23 },
24 {
25 $limit: 3
26 },
27 {
28 $project: {
29 "_id": 0,
30 "property_type": 1,
31 "address": 1,
32 score: { $meta: "searchScore" }
33 }
34 }
35])

以上查询会返回以下搜索结果:

1{
2 "property_type" : "Apartment",
3 "address" : {
4 "street" : "Hong Kong, Hong Kong Island, Hong Kong",
5 "suburb" : "Central & Western District",
6 "government_area" : "Central & Western",
7 "market" : "Hong Kong",
8 "country" : "Hong Kong",
9 "country_code" : "HK",
10 "location" : {
11 "type" : "Point",
12 "coordinates" : [ 114.15027, 22.28158 ],
13 "is_location_exact" : true
14 }
15 },
16 "score" : 1.177286982536316
17}
18{
19 "property_type" : "Apartment",
20 "address" : {
21 "street" : "Hong Kong, Hong Kong Island, Hong Kong",
22 "suburb" : "Central & Western District",
23 "government_area" : "Central & Western",
24 "market" : "Hong Kong",
25 "country" : "Hong Kong",
26 "country_code" : "HK",
27 "location" : {
28 "type" : "Point",
29 "coordinates" : [ 114.15082, 22.28161 ],
30 "is_location_exact" : true
31 }
32 },
33 "score" : 1.1236450672149658
34}
35{
36 "property_type" : "Apartment",
37 "address" : {
38 "street" : "Hong Kong,
39 Hong Kong Island, Hong Kong",
40 "suburb" : "Mid-Levels",
41 "government_area" : "Central & Western",
42 "market" : "Hong Kong",
43 "country" : "Hong Kong",
44 "country_code" : "HK",
45 "location" : {
46 "type" : "Point",
47 "coordinates" : [ 114.15007, 22.28215 ],
48 "is_location_exact" : true
49 }
50 },
51 "score" : 1.114811897277832
52}

后退

更多类似内容

来年

短语