Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Docs 菜单
Docs 主页
/ /

near (MongoDB搜索操作符)

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

near

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

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

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

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

您可以使用 near操作符查找接近数字或日期的结果。near操作符根据与数字或日期的接近程度对MongoDB搜索结果进行评分。

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

数字

用于计算MongoDB搜索结果文档分数的值。分数使用以下公式计算:

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 的信息,请参阅对结果中的文档进行评分

要学习;了解更多信息,请参阅对行为进行评分。

no

MongoDB Search score 是MongoDB Search 结果与 origin 的接近程度的度量。score01 之间调整,其中 1 为精确匹配,0 为远程匹配。当MongoDB搜索结果与 origin 的距离等于使用 pivot 计算的距原点的距离时,分数等于 0.5

near 操作符使用以下距离衰减函数来计算文档得分:

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

其中每个术语的定义如下:

因子
说明

pivot

指定为参考点的值,如果fieldValueorigin之间的距离等于0.5 ,则分数等于该值。 这定义了随着fieldValueorigin之间的距离增加,分数衰减的速度。 对于fieldValueorigin之间的给定距离,如果pivot减小,则分数也会减小。

distance

fieldValueorigin 之间的绝对距离。MongoDB Search 使用以下公式计算该值:

abs(fieldValue - origin)

其中:

  • fieldValue 是您在文档中查询的字段的值。

  • origin 是要在附近搜索的数字、日期或地理位置点。

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

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

If you load the sample data on your cluster, you can create the static indexes using the index definitions in the examples below or the dynamic index and run the example queries on your cluster.

提示

If you've already loaded the sample dataset, refer to the MongoDB Search Quick Start tutorial to create an index definition and run MongoDB Search queries.

以下示例使用 near 操作符查询数字字段。以下查询使用名为 runtimes 的索引,该索引动态地为 movies 集合中的所有字段创建索引。该查询在 movies 集合中搜索 runtime 字段值接近 279 的文档。

以下查询将返回所有符合搜索条件的文档。它包括一个用于将输出限制为 7 个结果的$limit阶段和一个用于执行以下操作的$project阶段:

  • 排除 titleruntime 之外的所有字段

  • 添加字段 score

score 是使用 pivot 计算得出。

1db.movies.aggregate([
2 {
3 $search: {
4 "index": "runtimes",
5 "near": {
6 "path": "year",
7 "origin": 2000,
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])
[
{ runtime: 279, title: 'The Kingdom', score: 1 },
{ runtime: 279, title: 'The Kingdom', score: 1 },
{ runtime: 279, title: 'The Jinx: The Life and Deaths of Robert Durst', score: 1 },
{ runtime: 281, title: 'Les Misèrables', score: 0.5 },
{ runtime: 277, title: 'Tokyo Trial', score: 0.5 },
{ runtime: 283, title: 'Scenes from a Marriage', score: 0.3333333432674408 },
{ runtime: 274, title: 'The Crimson Petal and the White', score: 0.2857142984867096 }
]

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

以下查询返回搜索条件的元数据结果。也就是说,它使用 $searchMeta 阶段来获取以下存储桶(年份)中符合搜索条件的电影数量:

  • 2000,包括此存储桶的下限

  • 2005,2000 存储桶的不含上限以及此存储桶的包含下限

  • 2010,2005 存储桶的不含上限以及此存储桶的包含下限

  • 2010,2010 存储桶的独占上限

1db.movies.aggregate([
2 {
3 "$searchMeta": {
4 "facet": {
5 "operator": {
6 "near": {
7 "path": "runtime",
8 "origin": 279,
9 "pivot": 2
10 }
11 },
12 "facets": {
13 "yearFacet": {
14 "type": "number",
15 "path": "year",
16 "boundaries": [2000, 2005, 2010, 2015 ]
17 }
18 }
19 }
20 }
21 }
22])
[
{
count: { lowerBound: Long('20910') },
facet: {
yearFacet: {
buckets: [
{ _id: 2000, count: Long('3058') },
{ _id: 2005, count: Long('4012') },
{ _id: 2010, count: Long('4669') }
]
}
}
}
]

以下示例使用 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 }

在上面的MongoDB 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 字段。

例子

The following query searches for properties in Portugal. It includes a $limit stage to limit the output to 3 results and a $project stage to:

  • 排除 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 字段。

例子

The following query searches for apartments in Hong Kong near a specified GeoJSON point. The query uses must to specify the search condition, which must be met, and should to specify preference for location. It includes a $limit stage to limit the output to 3 results and a $project stage to:

  • 排除 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}

后退

更多类似内容

在此页面上